本文介绍了使用ASP .NET成员和与MVC档案,我怎么可以创建一个用户并将其设置为HttpContext.Current.User?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实施了code自定义配置文件对象由Joel说明如下:

I implemented a custom Profile object in code as described by Joel here:

http://stackoverflow.com/questions/426609/asp-net-membership-how-to-assign-profile-values

我不能让它当我创建一个新用户,但是。当我这样做:

I can't get it to work when I'm creating a new user, however. When I do this:

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

用户创建并添加到数据库中的一个角色,但 HttpContext.Current.User 仍然是空的,而 Membership.GetUser( )返回null,所以这(从乔尔的code)不工作:

the user is created and added to a role in the database, but HttpContext.Current.User is still empty, and Membership.GetUser() returns null, so this (from Joel's code) doesn't work:

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

AccountProfile.CurrentUser.FullName = "Snoopy";

我已经打过电话 Membership.GetUser(用户名)并设置配置文件属性的方式,而是集性能保持为空,然后调用 AccountProfile .CurrentUser(用户名).Save()不会放任何东西在数据库中。我也试着指示用户是否有效和放大器;登录后,通过调用 Membership.ValidateUser FormsAuthentication.SetAuthCookie 等,但目前用户仍然空或匿名(根据我的浏览器的cookies的状态)。

I've tried calling Membership.GetUser(userName) and setting Profile properties that way, but the set properties remain empty, and calling AccountProfile.CurrentUser(userName).Save() doesn't put anything in the database. I've also tried indicating that the user is valid & logged in, by calling Membership.ValidateUser, FormsAuthentication.SetAuthCookie, etc., but the current user is still null or anonymous (depending on the state of my browser cookies).

解决(编辑整理此外,见下文):基于弗郎佩诺夫的解释和一些实验,我想通了这个问题。乔尔的code和我试着将只与现有档案工作的变化。如果没有配置文件存在, ProfileBase.Create(用户名)将在每次被称为时间返回一个新的空对象;您可以设置属性,但他们不会大棒,因为一个新的实例返回每次访问时间。设置 HttpContext.Current.User 到一个新的的GenericPrincipal 将会的给你一个User对象,但是的的配置文​​件对象, ProfileBase.Create(用户名) HttpContext.Current.Profile 仍然将指向新的,空的对象。

SOLVED (EDITED FURTHER, SEE BELOW): Based on Franci Penov's explanation and some more experimentation, I figured out the issue. Joel's code and the variations I tried will only work with an existing Profile. If no Profile exists, ProfileBase.Create(userName) will return a new empty object every time it's called; you can set properties, but they won't "stick" because a new instance is returned every time you access it. Setting HttpContext.Current.User to a new GenericPrincipal will give you a User object, but not a Profile object, and ProfileBase.Create(userName) and HttpContext.Current.Profile will still point to new, empty objects.

如果你想创建一个配置文件在同一请求新创建的用户,您需要调用 HttpContext.Current.Profile.Initialize(用户名,真实) 。然后,您可以填充初始化配置文件并保存它,这将是对将来的名称请求访问,因此乔尔的code会工作。我的只有的使用 HttpContext.Current.Profile 在内部,当我需要创建/创建时立即访问配置文件。任何其他要求,我用 ProfileBase.Create(用户名),我也只暴露该版本为公共的。

If you want to create a Profile for a newly-created User in the same request, you need to call HttpContext.Current.Profile.Initialize(userName, true). You can then populate the initialized profile and save it, and it will be accessible on future requests by name, so Joel's code will work. I am only using HttpContext.Current.Profile internally, when I need to create/access the Profile immediately upon creation. On any other requests, I use ProfileBase.Create(userName), and I've exposed only that version as public.

注意,弗郎是正确的:如果你愿意来创建用户(和角色),并设置为身份验证的第一个往返,并要求用户重新登录,您将能够访问配置文件通过对后续请求乔尔的code简单得多。是什么把我的是,角色是在用户创建无需任何初始化立即访问,但配置文件是没有的。

Note that Franci is correct: If you are willing to create the User (and Roles) and set it as Authenticated on the first round-trip, and ask the user to then log in, you will be able to access the Profile much more simply via Joel's code on the subsequent request. What threw me is that Roles is immediately accessible upon user creation without any initialization, but Profile is not.

我的新AccountProfile code:

My new AccountProfile code:

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不会是真的,直到后续请求。

Further thanks to Franci for explaining the Authentication life cycle - I'm calling FormsAuthentication.SetAuthCookie in my validation function, but I'm returning a bool to indicate success, because User.Identity.IsAuthenticated will not be true until the subsequent request.

修订版:我是个白痴。上述解释工作在狭窄的情况下,但没有解决的核心问题:调用的currentUser每次返回对象的新实例,无论是现有的配置文件或没有。由于它是定义为一个属性,我并没有考虑过这一点,并写道:

REVISED: I'm an idiot. The above explanation works in the narrow case, but doesn't resolve the core problem: Calling CurrentUser returns a new instance of the object each time, whether it's an existing Profile or not. Because it's defined as a property, I wasn't thinking about this, and wrote:

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

其中(当然)是行不通的。它应该是:

which (of course) doesn't work. It should be:

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

这是我自己的完全可俯瞰这个基本点故障,但我认为声明的currentUser作为一个属性意味着它是可以被操纵的对象。相反,它应该被声明为 GetCurrentUser()

推荐答案

创建用户只需将它添加到用户的列表中。然而,这并不认证或授权的当前请求的新用户。还需要在当前请求的上下文或后续请求的用户进行认证。

Creating a user just adds it to the list of users. However, this does not authenticate or authorize the new user for the current request. You also need to authenticate the user in the current request context or for subsequent requests.

Membership.ValidateUser 只会验证凭据,但它不验证当前或后续请求用户。 FormsAuthentication.SetAuthCookie 将设置在响应流中的身份验证票证,所以接下来的请求将被验证,但它不会影响当前请求的状态。

Membership.ValidateUser will only validate the credentials, but it's not authenticating the user for the current or subsequent requests. FormsAuthentication.SetAuthCookie will set the authentication ticket in the response stream, so the next request will be authenticated, but it does not affect the state of the current request.

对用户进行认证,最简单的方法是调用 FormsAuthentication.RedirectFromLoginPage (假设你在你的应用程序中使用窗体身份验证)。然而,这一个实际上会引起一个新的HTTP请求,将用户进行认证。

The easiest way to authenticate the user would be to call FormsAuthentication.RedirectFromLoginPage (assuming you are using forms authentication in your app). However, this one would actually cause a new HTTP request, which will authenticate the user.

另外,如果你需要继续你的逻辑来处理当前请求,但希望用户进行身份验证,可以创建一个的GenericPrincipal ,分配给它的身份新用户并设置 HttpContext.User中来的校长。

Alternatively, if you need to continue your logic for processing the current request, but want the user to be authenticated, you can create a GenericPrincipal, assign it the identity of the new user and set the HttpContext.User to that principal.

这篇关于使用ASP .NET成员和与MVC档案,我怎么可以创建一个用户并将其设置为HttpContext.Current.User?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 22:21