我有一些表具有与aspnet_Users.UserID相关的uniqueidentifier UserID。当用户为这些表提交一些数据时,由于控制器方法具有[Authorize],因此将获得一个User对象。我可以使用User.Identity.Name获取用户名,但是如何获取UserID才能建立(所有权)关系呢?
我有一些表具有与aspnet_Users.UserID相关的uniqueidentifier UserID。当用户为这些表提交一些数据时,由于控制器方法具有[Authorize],因此将获得一个User对象。我可以使用User.Identity.Name获取用户名,但是如何获取UserID才能建立(所有权)关系呢?
Answers:
似乎无法从User对象获取它,但是可以通过以下方式获取它:
Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey;
首先,这个答案严格来说不是MVC答案,而是ASP.NET答案。在这种情况下,您的站点是MVC的事实与解决该问题无关。
嗯 我不太确定您如何处理系统中的用户,但这听起来像是您在使用asp.net membership provider
.net开箱即用的(非常邪恶)。你说的事实暗示了这一点
对于使用默认FormsIdentity的默认表单身份验证系统,它只有一个名为Name的属性(如您正确指出的那样)。这意味着它只有一个值可以放置一些唯一的用户信息。对于您的情况,您要将Name / UserName / DisplayName放在Name
属性中。我假设这个名称是他们的显示名称,并且是唯一的。无论您在这里拥有什么价值,它都必须是唯一的。
由此,您可以抓住用户的向导。
看一下这个。
using System.Web.Security;
....
// NOTE: This is a static method .. which makes things easier to use.
MembershipUser user = Membership.GetUser(User.Identity.Name);
if (user == null)
{
throw new InvalidOperationException("User [" +
User.Identity.Name + " ] not found.");
}
// Do whatever u want with the unique identifier.
Guid guid = (Guid)user.ProviderUserKey;
因此,每次您希望获取用户信息时,都需要使用上述静态方法从数据库中获取信息。
阅读有关MSDN上的Membership类和MembershipUser类的所有信息。
因此,我会缓存该结果,因此您无需继续访问数据库。
... cont from above....
Guid guid = (Guid)user.ProviderUserKey;
Cache.Add(User.Identity.Name, user.UserID); // Key: Username; Value: Guid.
否则,您可以创建自己的Identity类(继承自IIdentity)并添加您自己的自定义属性,例如UserID
。然后,每当您进行身份验证(以及每个请求)时,都可以设置此值。无论如何,这是一个硬核解决方案,所以现在就进行缓存。
高温超导
User.Identity
是IPrincipal
-通常为System.Web.Security.FormsIdentity
它对UserID一无所知-只是对“身份”概念的抽象。
该IIdentity的接口只有“名称”为用户,甚至没有“用户名”。
如果您使用默认的MVC4,则SimpleMembershipProvider
可以执行以下操作:
WebSecurity.GetUserId(User.Identity.Name) // User is on ControllerBase
(在WebMatrixWebSecurity
的nuget包Microsoft.AspNet.WebPages.WebData
中
您也可以使用
WebSecurity.CurrentUserName
WebSecurity.CurrentUserId
(如果您使用的是ASPNetMembershipProvider,它是较旧的更复杂的ASPNET成员资格系统,请参阅@ eduncan911的回答)
WebSecurity.CurrentUserId
。即使模板化的AccountControllerWebSecurity.GetUserId(User.Identity.Name)
在CurrentUserId
可用时也使用它似乎有些愚蠢。
如果您使用的是ASP.NET成员资格(依次使用IPrincipal对象):
using System.Web.Security;
{
MembershipUser user = Membership.GetUser(HttpContext.User.Identity.Name);
Guid guid = (Guid)user.ProviderUserKey;
}
User.Identity始终返回当前用户的状态,无论是否登录。
是否匿名,等等。因此检查已登录:
if (User.Identity.IsAuthenticated)
{
...
}
因此,将它们放在一起:
using System.Web.Security;
{
if (User.Identity.IsAuthenticated)
{
MembershipUser user = Membership.GetUser(HttpContext.User.Identity.Name);
Guid guid = (Guid)user.ProviderUserKey;
}
}
如果您使用自己的IPrincipal对象进行授权,则只需将其强制转换即可访问ID。
例如:
public class MyCustomUser : IPrincipal
{
public int UserId {get;set;}
//...Other IPrincipal stuff
}
这是有关创建自己的基于表单的身份验证的出色教程。
http://www.codeproject.com/KB/web-security/AspNetCustomAuth.aspx
这样可以使您正确地为用户创建身份验证cookie并访问自定义用户数据。
简单....
int userID = WebSecurity.CurrentUserId;
通常,您只能使用WebSecurity.currentUserId
,但是如果您在创建帐户之后就进入AccountController,并且想要使用用户ID将用户链接到其他表中的某些数据,那么WebSecurity.currentUserId
(以及上面的所有解决方案),在那种情况下返回-1,所以它不起作用。
幸运的是,在这种情况下,您可以方便地使用UserProfiles表的db上下文,因此可以通过以下方式获取用户ID:
UserProfile profile = db.UserProfiles.Where(
u => u.UserName.Equals(model.UserName)
).SingleOrDefault();
我最近遇到了这个案例,这个答案可以节省我很多时间,所以就把它放在那里。