asp.net-mvc – 使用ASP.NET会员资格和配置文件与MVC,如何创建一个用户并将其设置为HttpContext.Current.User?

我在代码中实现了一个自定义的Profile对象,如Joel所述:

How to assign Profile values?

但是,当我创建一个新用户时,我无法让它工作。当我这样做:

Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");

创建用户并将其添加到数据库中的角色,但HttpContext.Current.User仍为空,Membership.GetUser()返回null,因此(来自Joel的代码)不起作用:

static public AccountProfile CurrentUser
{
    get { return (AccountProfile)
                     (ProfileBase.Create(Membership.GetUser().UserName)); }
}

AccountProfile.CurrentUser.FullName = "Snoopy";

我尝试调用Membership.GetUser(userName),并以这种方式设置Profile属性,但是set属性保持为空,并调用AccountProfile.CurrentUser(userName).Save()不会在数据库中放入任何东西。我也试过指出用户是有效的通过调用Membership.ValidateUser,FormsAuthentication.SetAuthCookie等登录,但当前用户仍然为空或匿名(取决于浏览器Cookie的状态)。

解决方案(再次参见下文):基于Franci Penov的解释和一些更多的实验,我想出了这个问题。 Joel的代码和我尝试的变体将只适用于现有的配置文件。如果没有Profile,ProfileBase.Create(userName)将在每次调用时返回一个新的空对象;您可以设置属性,但是它们不会“粘贴”,因为每次访问新实例时都会返回。将HttpContext.Current.User设置为新的GenericPrincipal将为您提供一个User对象,但不会提供Profile对象,而ProfileBase.Create(userName)和HttpContext.Current.Profile仍将指向新的空对象。

如果要在同一请求中为新创建的用户创建配置文件,则需要调用HttpContext.Current.Profile.Initialize(userName,true)。然后,您可以填充初始化的配置文件并将其保存,并且可以根据未来的请求按名称访问,因此Joel的代码将工作。我在内部只使用HttpContext.Current.Profile,当我需要在创建时立即创建/访问配置文件。在任何其他请求中,我使用ProfileBase.Create(userName),而且我已经公开了该版本。

请注意,Franci是正确的:如果您愿意创建用户(和角色),并将其设置为第一次往返验证,并要求用户登录,您将能够更简单地访问该配置文件通过Joel的代码对后续的请求。扔给我的是,用户创建后立即可以访问角色,无需任何初始化,但Profile不是。

我的新AccountProfile代码:

public static AccountProfile CurrentUser
{
    get
    {
        if (Membership.GetUser() != null)
            return ProfileBase.Create(Membership.GetUser().UserName) as AccountProfile;
        else
            return null;
    }
}

internal static AccountProfile NewUser
{
    get { return System.Web.HttpContext.Current.Profile as AccountProfile; }
}

新用户创建:

MembershipUser user = Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyBasicUserRole");
AccountProfile.NewUser.Initialize(userName, true);
AccountProfile.NewUser.FullName = "Snoopy";
AccountProfile.NewUser.Save();

后续访问:

if (Membership.ValidateUser(userName, password))
{
    string name = AccountProfile.CurrentUser.FullName;
}

进一步感谢Franci解释身份验证生命周期 – 我在验证函数中调用FormsAuthentication.SetAuthCookie,但是我返回一个bool来指示成功,因为在后续请求之后,User.Identity.IsAuthenticated将不会为true。

修改:我是个白痴上述说明在狭义的情况下工作,但不解决核心问题:Calling CurrentUser每次返回对象的新实例,无论它是否是现有的Profile。因为它被定义为一个财产,我没有想到这个,并写道:

AccountProfile.CurrentUser.FullName = "Snoopy";
AccountProfile.CurrentUser.OtherProperty = "ABC";
AccountProfile.CurrentUser.Save();

这当然不行。它应该是:

AccountProfile currentProfile = AccountProfile.CurrentUser;
currentProfile.FullName = "Snoopy";
currentProfile.OtherProperty = "ABC";
currentProfile.Save();

完全忽略这个基本点是我自己的错,但我认为将CurrentUser声明为属性意味着它是一个可以被操纵的对象。而应该被声明为GetCurrentUser()。

创建用户只需将其添加到用户列表中即可。但是,这不会对当前请求的新用户进行身份验证或授权。您还需要在当前请求上下文或后续请求中验证用户。

Membership.ValidateUser只会验证凭据,但不会对当前或后续请求的用户进行身份验证。 FormsAuthentication.SetAuthCookie将在响应流中设置认证凭证,因此下一个请求将被认证,但不会影响当前请求的状态。

验证用户最简单的方法是调用FormsAuthentication.RedirectFromLoginPage(假设您在应用程序中使用表单验证)。但是,这实际上会导致一个新的HTTP请求,它将验证用户。

或者,如果您需要继续处理当前请求的逻辑,但希望用户进行身份验证,则可以创建一个GenericPrincipal,为其分配新用户的身份,并将HttpContext.User设置为该主体。

翻译自:https://stackoverflow.com/questions/2547290/using-asp-net-membership-and-profile-with-mvc-how-can-i-create-a-user-and-set

转载注明原文:asp.net-mvc – 使用ASP.NET会员资格和配置文件与MVC,如何创建一个用户并将其设置为HttpContext.Current.User?