Question

I am building an MVC 4 web application with simple membership provider and i have administration where i can edit user's username and password.When i edit just username or password it is okay, but when i try to edit both username and password at the same time when i try to log in with the new username the UserProfiles username that is shown in the users list is the old one, although the record in the database has changed.Here is a code sample :

[HttpPost]
    public ActionResult EditUser(RegisterUserModel model, FormCollection form)
    {
        if (ModelState.IsValid)
        {
            var oldUserName = form["userHidden"];
            var newUserName = model.UserName;
            bool isOldPassword = Membership.ValidateUser(oldUserName , model.Password);

            if (!isOldPassword)
            {
                var token = WebSecurity.GeneratePasswordResetToken(oldUserName );

                try
                {
                    //Reset password using the reset token and the new password
                    WebSecurity.ResetPassword(token, model.Password);

                }
                catch (Exception e)
                {
                    ModelState.AddModelError("", String.Format("{0} Exception caught.", e));
                }
            }

            if (newUserName != null && oldUserName != null)
            {
                if (newUserName.ToLower() != oldUserName.ToLower())
                {
                    myRepository.ChangeUserName(oldUserName, newUserName);
                    myRepository.Save();
                }
            }

            return RedirectToAction("Users", "Administration");
        }

        ModelState.AddModelError("", "Please enter correct username and password.");
        return View(model);
    }

And here is my ChangeUserName method:

public void ChangeUserName(string oldUserName, string newUserName)
    {
        var userToUpdate = (from user
                            in context.Users
                            where user.Username == oldUserName
                            select user).FirstOrDefault();

        if (userToUpdate != null)
        {
            var updatedUser = new Users();
            updatedUser.UserId = userToUpdate.UserId;
            updatedUser.UserName = newUserName;

            context.Entry(userToUpdate).CurrentValues.SetValues(updatedUser);
        }
    }

I have extended my membership like this:

public class ExtendMembership
{
    private static IMyRepository myRepository= new MyRepository(new MyEntities());

    public static bool ValidateUser(string username, string password, string companyName)
    {
        int companyId = myRepository.GetCompanyName(companyName);

        int? userId = companyId == 0 ? null : GetUserId(username, companyId);

        if (userId.HasValue && userId.Value != 0)
        {
            var userKeyToCompany = username + "@" + companyName.ToLower();
            return WebSecurity.Login(userKeyToCompany , password);
        }
        else
        {
            return false;
        }
    }

    private static int? GetUserId(string username, int companyId)
    {
        var userId = (from users
                      in myRepository.GetUsers()
                      where (users.UserName.ToLower() == username.ToLower()) && (users.CompanyId == companyId)
                      select users.UserId).FirstOrDefault();
        return userId;
    }
}

The GetUserId method fetches the id of the user for company

Was it helpful?

Solution 2

It turns out that my GetUserId method should be in MyRepository implemented on the changed context and also change password and change username actions should be separated. That solved everything.

OTHER TIPS

You should consider using construction instead of the static repository. Static repositories would fire back if you handle lots of requests. Here is a sample of the using you could use :

using(var myRepository = new MyRepository(new MyEntities())) {
   ... code here
} 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top