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?
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.
The "raw" Forms authentication built into the MVC template does not automatically load the profile. All it does is validate the user against the Membership tables and set the login cookie. If you want profile data persisted in Session state on login, you'll have to do that explicitly:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
LoadProfile(model.UserName);
}
}
private void LoadProfile(string UserName)
{
MyModelContext ctx = new MyModelContext(); //EF or LINQ2SQL context
var user = ctx.Users.Where(u => u.UserName == UserName).FirstOrDefault();
Session.Add("CurrentUser", user);
}
UPDATE:
I misunderstood the original question. You have to create and save a profile of type ProfileCommon
for anonymous users. See this post:
http://forums.asp.net/p/1150958/2619264.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With