使用ASP .NET成员和与MVC档案,我怎么可以创建一个用户并将其设置为HttpContext.Current.User?
-
23-09-2019 - |
题
我实现在代码的自定义配置文件对象作为由Joel这里描述:
我无法得到它的工作,当我创建一个新用户,但是。当我这样做:
Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");
在创建用户并添加到数据库中的一个角色,但HttpContext.Current.User
仍然是空的,并且Membership.GetUser()
返回NULL,所以这(从乔尔的代码)不工作:
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的状态)。
解决(编辑整理此外,见下文):基于弗郎佩诺夫的解释和一些实验,我想通了这个问题。乔尔的代码,我试图将只与现有档案工作的变化。如果没有配置文件存在,将ProfileBase.Create(userName)
每次被称为时间返回一个新的空对象;您可以设置属性,但他们不会“大棒”,因为一个新的实例返回每次访问时间。设置HttpContext.Current.User
到一个新的GenericPrincipal
的将的给你一个User对象,但的不的配置文件对象,ProfileBase.Create(userName)
和HttpContext.Current.Profile
仍将指向新的,空的对象。
如果您要创建在同一个请求一个新创建的用户配置文件,你需要调用HttpContext.Current.Profile.Initialize(userName, true)
。然后,您可以填充初始化的配置文件并保存它,这将是未来通过名称请求访问,因此乔尔的代码将工作。我的只有的使用HttpContext.Current.Profile
内部,当我需要在创建时立即创建/访问配置文件。在任何其他请求,我用ProfileBase.Create(userName)
,我也只露出该版本为公共的。
请注意,弗郎是正确的:如果你愿意来创建用户(和角色),把它作为身份验证的第一个往返,并要求用户再登录,您将能够访问配置文件更简单地通过乔尔对后续请求的代码。是什么把我的是,角色是根据用户创建可立即访问没有任何初始化,但档案是不是。
我的新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;
}
另外感谢弗郎解释验证生命周期 - 我打电话我的验证功能FormsAuthentication.SetAuthCookie,但我返回一个布尔值表明成功,因为User.Identity.IsAuthenticated不会是真的,直到后续请求。
<强>修订版强>我是白痴。上述解释工作在狭窄的情况下,但没有解决的核心问题:调用CurrentUser返回对象的新实例每次,无论是现有的配置文件或没有。因为它被定义为一个属性,我并没有考虑过这一点,并写道:
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
到校长。
其他提示
您如果启用anonymousIdentification会遇到的问题这种方法。而不是Membership.GetUser():用户名,我建议使用HttpContext.Profile.UserName。
喜欢这张...
private UserProfile _profile;
private UserProfile Profile
{
get { return _profile ?? (_profile = (UserProfile)ProfileBase.Create(HttpContext.Profile.UserName)); }
}
首先,感谢@Jeremy分享您的发现。你帮我在正确的方向走了。其次,对不起,撞到这个老帖子。希望这将有助于有人点连接起来。
我终于得到这个工作的方法是使用下面的静态方法我的个人资料类中:
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();
}