title: ASP.NET MVC 2 and SQL Table Profile Provider
body: <p>I'm trying to add the sample table profile provider from <a href="http://www.asp.net/downloads/sandbox/table-profile-provider-samples" rel="nofollow noreferrer">http://www.asp.net/downloads/sandbox/table-profile-provider-samples</a> to a new MVC 2 site.</p>
  
  <p>After a bit of research and fiddling around, I've arrived at a profile class that looks like this.</p>
  
  <pre><code>namespace MyNamespace.Models
  {
      public class UserProfile : ProfileBase
      {
          [SettingsAllowAnonymous(false),CustomProviderData("FirstName;nvarchar")]
          public string FirstName
          {
              get { return base["FirstName"] as string; }
              set { base["FirstName"] = value; }
          }
  
          [SettingsAllowAnonymous(false),CustomProviderData("LastName;nvarchar")]
          public string LastName
          {
              get { return base["LastName"] as string; }
              set { base["LastName"] = value; }
          }
  
          public static UserProfile GetUserProfile(string username)
          {
              return Create(username,false) as UserProfile;
          }
  
          public static UserProfile GetUserProfile()
          {
              return Create(Membership.GetUser().UserName,true) as UserProfile;
          }
      }
  }
  </code></pre>
  
  <p>And a web.config like</p>
  
  <pre><code>&lt;profile enabled="true" defaultProvider="TableProfileProvider" inherits="MyNamespace.Models.UserProfile"&gt;
    &lt;providers&gt;
      &lt;clear /&gt;
      &lt;add name="TableProfileProvider" type="Microsoft.Samples.SqlTableProfileProvider" connectionStringName="ContentDB" table="aspnet_UserProfiles" applicationName="/"/&gt;
    &lt;/providers&gt;
  &lt;/profile&gt;
  </code></pre>
  
  <p>Things I think I've found out along the way are</p>
  
  <ul>
  <li>Using a custom provider with MVC requires the "inherits" attribute on the <code>&lt;profile&gt;</code> element in web.config, which precludes the use of a <code>&lt;properties&gt;&lt;add ....&gt;</code> construct with the same profile field name.</li>
  <li>The sample SQL table profile provider needs the <code>CustomProviderData</code> attribute and, because of the above, it cannot appear in the web.config file, so needs to be added as an attribute to the properties in the profile class.</li>
  </ul>
  
  <p>It all seems to work OK <strong>once a user is logged in</strong>. However, I want to capture some profile data as part of the new user registration process, and I cannot seem to access the profile object until the user has logged in.</p>
  
  <p>I've tried adding a call to save profile data in the new user registration section of the MVC template code:</p>
  
  <pre><code>FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
  UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName);
  profile.FirstName = "Doug";
  Profile.Save();
  return RedirectToAction("Index", "Home");
  </code></pre>
  
  <p>However it seems that <code>Membership.GetUser()</code> is null until the user actually logs in. I also tried using the user's name from the model.</p>
  
  <pre><code>FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
  UserProfile profile = UserProfile.GetUserProfile(model.UserName);
  profile.FirstName = "Doug";
  profile.Save();
  return RedirectToAction("Index", "Home");
  </code></pre>
  
  <p>This gets a bit further, but fails when trying to set the FirstName profile field, with an error message along the lines of "trying to set an attribute as an anonymous user, but this is not allowed" (sorry, don't have access to the exact message as I'm typing this).</p>
  
  <p>Is there any way round this? It looks like the <code>FormsServer.SignIn</code> method does not actually log the user in as far as forms authentication is concerned, and it needs a round trip to be fully logged in, presumably needing the cookie to be submitted back to the server.</p>
  
  <p>If there's no easy way round this I could populate the profile table directly using data access methods (insert into aspnet_UserProfiles ....). Is this a bridge too far, or is it a viable solution?</p>
  
  <hr>
  
  <p>Hasn't anyone got this problem? No? Just me then!</p>
  
  <p>Just to update, I've tried the suggestion Franci Penov makes in his answer to this <a href="https://stackoverflow.com/questions/2547290/using-asp-net-membership-and-profile-with-mvc-how-can-i-create-a-user-and-set-i">posting</a>.</p>
  
  <p>So, now my code looks like this.</p>
  
  <pre><code>            FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
  
              GenericIdentity id = new GenericIdentity(model.UserName);
              HttpContext.User = new GenericPrincipal(id, null);
  
              UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName) as UserProfile;
              profile.FirstName = "Doug";
              profile.Save();
  
              return RedirectToAction("Index", "Home");
  </code></pre>
  
  <p>Now, at least the call to Membership.GetUser() returns a valid <code>MembershipUser</code> object, but trying to set the FirstName profile property still results in the message <code>This property cannot be set for anonymous users.</code></p>
  
  <p>So, the user is logged on as far as Membership is concerned, but the Profile system still thinks not.</p>
  
  <p>Any ideas?</p>