首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用ASP的.NET成员资格和配置文件,如何创建用户并将其设置为HttpContext.Current.User?

使用ASP的.NET成员资格和配置文件,如何创建用户并将其设置为HttpContext.Current.User?
EN

Stack Overflow用户
提问于 2010-03-31 01:38:16
回答 3查看 14.2K关注 0票数 17

我在代码中实现了一个自定义配置文件对象,正如Joel在这里所描述的:

How to assign Profile values?

然而,当我创建一个新用户时,我不能让它工作。当我这样做的时候:

代码语言:javascript
复制
Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");

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

代码语言:javascript
复制
static public AccountProfile CurrentUser
{
    get { return (AccountProfile)
                     (ProfileBase.Create(Membership.GetUser().UserName)); }
}

AccountProfile.CurrentUser.FullName = "Snoopy";

我尝试过调用Membership.GetUser(userName)并以这种方式设置配置文件属性,但是设置的属性仍然是空的,并且调用AccountProfile.CurrentUser(userName).Save()不会在数据库中放入任何内容。我还尝试通过调用Membership.ValidateUserFormsAuthentication.SetAuthCookie等来指示用户是有效的&已登录,但当前用户仍然是空的或匿名的(取决于浏览器cookie的状态)。

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

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

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

我的新AccountProfile代码:

代码语言:javascript
复制
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; }
}

创建新用户:

代码语言:javascript
复制
MembershipUser user = Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyBasicUserRole");
AccountProfile.NewUser.Initialize(userName, true);
AccountProfile.NewUser.FullName = "Snoopy";
AccountProfile.NewUser.Save();

后续访问:

代码语言:javascript
复制
if (Membership.ValidateUser(userName, password))
{
    string name = AccountProfile.CurrentUser.FullName;
}

进一步感谢Franci解释了身份验证生命周期-我在我的验证函数中调用了FormsAuthentication.SetAuthCookie,但我返回了一个布尔值来表示成功,因为User.Identity.IsAuthenticated在后续请求之前不会为真。

修正:我是个笨蛋。上面的解释适用于狭义的情况,但没有解决核心问题:每次调用CurrentUser都会返回对象的一个新实例,无论它是否为现有的概要文件。因为它被定义为属性,所以我没有考虑到这一点,并写道:

代码语言:javascript
复制
AccountProfile.CurrentUser.FullName = "Snoopy";
AccountProfile.CurrentUser.OtherProperty = "ABC";
AccountProfile.CurrentUser.Save();

这(当然)不起作用。它应该是:

代码语言:javascript
复制
AccountProfile currentProfile = AccountProfile.CurrentUser;
currentProfile.FullName = "Snoopy";
currentProfile.OtherProperty = "ABC";
currentProfile.Save();

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-31 02:01:03

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

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

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

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

票数 7
EN

Stack Overflow用户

发布于 2012-01-22 05:27:32

如果启用anonymousIdentification,您将会遇到这种方法的问题。我建议使用HttpContext.Profile.UserName而不是Membership.GetUser().UserName。

像这样..。

代码语言:javascript
复制
private UserProfile _profile;
private UserProfile Profile
{
    get { return _profile ?? (_profile = (UserProfile)ProfileBase.Create(HttpContext.Profile.UserName)); }
}

帽子提示:SqlProfileProvider - can you use Profile.GetProfile() in a project?

票数 1
EN

Stack Overflow用户

发布于 2011-07-02 06:20:11

首先,感谢@Jeremy分享您的发现。你帮我走上了正确的方向。其次,很抱歉撞到了这个老帖子。希望这能帮助一些人把这些点联系起来。

我最终成功的方法是在我的profile类中使用下面的静态方法:

代码语言:javascript
复制
internal static void InitializeNewMerchant(string username, Merchant merchant)
{
    var profile = System.Web.HttpContext.Current.Profile as MerchantProfile;
    profile.Initialize(username, true);
    profile.MerchantId = merchant.MerchantId;
    profile.Save();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2547290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档