I am able to change 开发者_StackOverflowa username by directly accessing the asp.net membership user tables. However, the old username is preserved in a new row and assigned a new UserID automatically by asp.net. How do I stop that from happening?
EDIT: only in the users table and roles table, not the membership table.
var mUser = dc.aspnet_Users
.Where(u => u.UserId == (Guid)user.ProviderUserKey)
.Select(u => u).SingleOrDefault();
mUser.UserName = newName;
mUser.LoweredUserName = newName.ToLower();
try
{
dc.SubmitChanges();
}
catch
{
...
}
Changing username is not supported by the sql membership provider in ASP.NET 2.0. You can still change the username but you have to use custom implementation.
Also you have to update the membership cookie with the new username in order to avoid recreation of the user with the same username but new UserId.
In the example below I use Linq to SQL to update the membership tables - I have data context called MembershipDataContext.
public bool ChangeUserName(Guid userId, string newUserName)
{
bool success = false;
newUserName = newUserName.Trim();
// Make sure there is no user with the new username
if (Membership.GetUser(newUserName) == null)
{
MembershipUser u = Membership.GetUser(userId);
string oldUsername = u.UserName;
// get current application
MembershipDataContext context = new MembershipDataContext ();
aspnet_User userToChange = (from user in context.aspnet_Users
where user.UserId == userId
select user).FirstOrDefault();
if (userToChange != null)
{
userToChange.UserName = newUserName;
userToChange.LoweredUserName = newUserName.ToLower();
context.SubmitChanges();
// ASP.NET Issues a cookie with the user name.
// When a request is made with the specified cookie,
// ASP.NET creates a row in aspnet_users table.
// To prevent this sign out the user and then sign it in
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie =
HttpContext.Current.Request.Cookies[cookieName];
FormsAuthenticationTicket authTicket = null;
try
{
authTicket =
FormsAuthentication.Decrypt(authCookie.Value);
FormsIdentity formsIdentity =
new FormsIdentity(
new FormsAuthenticationTicket(
authTicket.Version,
newUserName,
authTicket.IssueDate,
authTicket.Expiration,
authTicket.IsPersistent,
authTicket.UserData));
string y = HttpContext.Current.User.Identity.Name;
string[] roles =
authTicket.UserData.Split(new char[] { '|' });
System.Security.Principal.GenericPrincipal genericPrincipal =
new System.Security.Principal.GenericPrincipal(
formsIdentity,
roles);
HttpContext.Current.User = genericPrincipal;
}
catch (ArgumentException ex)
{
// Handle exceptions
}
catch( NullReferenceException ex)
{
// Handle exceptions
}
FormsAuthentication.SignOut();
HttpContext.Current.Session.Abandon();
FormsAuthentication.SetAuthCookie(newUserName, false);
success = true;
}
}
return success;
}
You have to change both UserName and LoweredUserName... I assume the API used the other field, did the lookup, observed the record didn't exist (because the one was changed), and created a new one. Typically, it doesn't preserve the old records.
EDIT: Could the issue also be you are looking up the account by the ProviderUserKey field?
How did you change the username? I just did it by using an update sql statement and updated the username without creating new rows or preserving the old username.
UPDATE [MyDatabase].[dbo].[aspnet_Users]
SET [UserName] = 'mynewusername',
[LoweredUserName] = LOWER('mynewusername')
WHERE [UserName] = 'myusername'
精彩评论