I'm trying to add the sample table profile provider from http://www.asp.net/downloads/sandbox/table-profile-provider-samples to a new MVC 2 site.
After a bit of research and fiddling around, I've arrived at a profile class that looks like this.
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;
}
}
}
And a web.config like
<profile enabled="true" defaultProvider="TableProfileProvider" inherits="MyNamespace.Models.UserProfile">
<providers>
<clear />
<add name="TableProfileProvider" type="Microsoft.Samples.SqlTableProfileProvider" connectionStringName="ContentDB" table="aspnet_UserProfiles" applicationName="/"/>
</providers>
</profile>
Things I think I've found out along the way are
- Using a custom provider with MVC requires the "inherits" attribute on the
<profile>
element in web.config, which precludes the use of a<properties><add ....>
construct with the same profile field name. - The sample SQL table profile provider needs the
CustomProviderData
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.
It all seems to work OK once a user is logged in. 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.
I've tried adding a call to save profile data in the new user registration section of the MVC template code:
FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName);
profile.FirstName = "Doug";
Profile.Save();
return RedirectToAction("Index", "Home");
However it seems that Membership.GetUser()
is null until the user actually logs in. I also tried using the user's name from the model.
FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
UserProfile profile = UserProfile.GetUserProfile(model.UserName);
profile.FirstName = "Doug";
profile.Save();
return RedirectToAction("Index", "Home");
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).
Is there any way round this? It looks like the FormsServer.SignIn
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.
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 bodge too far, or is it a viable solution?
Thanks in advance.
Doug