Search code examples
c#asp.net-mvc-2asp.net-membershipvisual-web-developerasp.net-profiles

How to load the profile of a newly-logged-in user before the redirect


I started an ASP.NET MVC 2 project and I am building off of the code that was generated automatically.

The problem that I am experiencing is that after a user is logged in, it appears that the profile of the newly-logged-in user is not loaded into the HttpContext, so I get a ProviderException with the message "This property cannot be set for anonymous users" when attempting to set a property value in the current user's profile.

For the POST-only LogOn action, Visual Web Developer 2010 Express basically generated:

    [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            if (MembershipService.ValidateUser(model.UserName, model.Password))
            {
                FormsService.SignIn(model.UserName, model.RememberMe);
        //...

where FormsService is a property of the controller of type FormsAuthenticationService (also generated):

public class FormsAuthenticationService : IFormsAuthenticationService
{
    public void SignIn(string userName, bool createPersistentCookie)
    {
        if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");

        FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
    }

    public void SignOut()
    {
        FormsAuthentication.SignOut();
    }
}

After the FormsService.SignIn(model.UserName, model.RememberMe) line I was assuming that information for the newly-logged-in account would be immediately available to the controller, but this does not appear to be the case. If, for example, I add profile.SetPropertyValue("MyProfileProperty", "test") below the call to FormsService#SignIn, then I get the ProviderException "This property cannot be set for anonymous users".

How do I load the newly-logged-in user's profile into the HttpContext so that I can set a property value in his or her profile before the next request?


Solution

  • The naming of the function is counter intuitive, but ProfileBase.Create(username) will load the existing profile for an existing user or create a new profile if none exists.

    var profile = ProfileBase.Create(userName);
    

    This will not load the profile into ControllerContext.HttpContext.Profile but at least you can access or alter the user profile.