gpt4 book ai didi

asp.net-mvc - 将 ASP .NET 成员身份和配置文件与 MVC 结合使用,如何创建用户并将其设置为 HttpContext.Current.User?

转载 作者:行者123 更新时间:2023-12-01 23:50:38 24 4
gpt4 key购买 nike

我按照 Joel 的描述在代码中实现了一个自定义 Profile 对象:

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) 并以这种方式设置配置文件属性,但设置的属性仍为空,并调用 AccountProfile.CurrentUser(userName).Save() 不会将任何内容放入数据库中。我还尝试通过调用Membership.ValidateUser、FormsAuthentication.SetAuthCookie等来指示用户有效并已登录,但当前用户仍然为空或匿名(取决于我的浏览器 cookie 的状态)。

已解决(进一步编辑,见下文):根据 Franci Penov 的解释和更多实验,我解决了这个问题。乔尔的代码和我尝试的变体仅适用于现有的配置文件。如果不存在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),并且仅将该版本公开为公共(public)版本。

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

我的新帐户配置文件代码:

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请求。

修订:我是个白痴。上面的解释适用于狭隘的情况,但没有解决核心问题:调用 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 到该主体。

关于asp.net-mvc - 将 ASP .NET 成员身份和配置文件与 MVC 结合使用,如何创建用户并将其设置为 HttpContext.Current.User?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2547290/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com