ASP.NET MVC 5-身份.如何获取当前的ApplicationUser [英] ASP.NET MVC 5 - Identity. How to get current ApplicationUser

查看:87
本文介绍了ASP.NET MVC 5-身份.如何获取当前的ApplicationUser的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目中有一个Article实体,该实体具有名为AuthorApplicationUser属性.如何获取当前记录的ApplicationUser的完整对象?创建新文章时,我必须将Article中的Author属性设置为当前的ApplicationUser.

在旧的成员资格机制中,这很简单,但是在新的身份方法中,我不知道该怎么做.

我尝试过这种方式:

  • 为Identity扩展添加using语句:using Microsoft.AspNet.Identity;
  • 然后我尝试获取当前用户:ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == User.Identity.GetUserId());

但是我得到以下异常:

LINQ to Entities无法识别方法'System.String GetUserId(System.Security.Principal.IIdentity)',并且该方法无法转换为商店表达式. Source = EntityFramework

解决方案

您不需要直接向数据库查询当前的ApplicationUser.

这引入了新的依赖关系,即为初学者提供了额外的上下文,但是以后用户数据库表发生了变化(过去2年中有3次变化),但API保持一致.例如,现在users表在Identity Framework中现在称为AspNetUsers,并且几个主键字段的名称一直在变化,因此,<答案>原样中的几个答案中的代码将不再起作用./p>

另一个问题是对数据库的基础OWIN访问将使用单独的上下文,因此来自单独的SQL访问的更改可能会产生无效的结果(例如,看不到对数据库所做的更改).同样,解决方案是使用提供的API,而不是尝试解决.

以ASP.Net身份(当前日期)访问当前用户对象的正确方法是:

var user = UserManager.FindById(User.Identity.GetUserId());

或者,如果您有异步操作,则类似于:

var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());

FindById要求您具有以下using语句,以便非异步UserManager方法可用(它们是UserManager的 extension方法,因此,如果您不包括此方法,则仅参见FindByIdAsync):

using Microsoft.AspNet.Identity;

如果您根本不在控制器中(例如,您正在使用IOC注入),那么将从以下位置完整检索用户ID:

System.Web.HttpContext.Current.User.Identity.GetUserId();

如果您不在标准帐户控制器中,则需要将以下内容(例如)添加到您的控制器中:

1.添加以下两个属性:

    /// <summary>
    /// Application DB context
    /// </summary>
    protected ApplicationDbContext ApplicationDbContext { get; set; }

    /// <summary>
    /// User manager - attached to application DB context
    /// </summary>
    protected UserManager<ApplicationUser> UserManager { get; set; }

2.将其添加到Controller的构造函数中:

    this.ApplicationDbContext = new ApplicationDbContext();
    this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.ApplicationDbContext));

2015年3月更新

注意:身份框架的最新更新更改了用于身份验证的基础类之一.现在,您可以从当前HttpContent的Owin上下文中访问它.

ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());

附录:

在EF和Identity Framework与Azure一起使用时,通过远程数据库连接(例如,对Azure数据库的本地主机测试),您可以随意打出可怕的错误:19-物理连接不可用".由于原因被隐藏在Identity Framework中,您无法在其中添加重试(或缺少.Include(x->someTable)的内容),因此您需要在项目中实现自定义SqlAzureExecutionStrategy.

I have an Article entity in my project which has the ApplicationUser property named Author. How can I get the full object of currently logged ApplicationUser? While creating a new article, I have to set the Author property in Article to the current ApplicationUser.

In the old Membership mechanism it was simple, but in the new Identity approach I don't know how to do this.

I tried to do it this way:

  • Add using statement for Identity extensions: using Microsoft.AspNet.Identity;
  • Then I try to get the current user: ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == User.Identity.GetUserId());

But I get the following exception:

LINQ to Entities does not recognize the method 'System.String GetUserId(System.Security.Principal.IIdentity)' method, and this method cannot be translated into a store expression. Source=EntityFramework

解决方案

You should not need to query the database directly for the current ApplicationUser.

That introduces a new dependency of having an extra context for starters, but going forward the user database tables change (3 times in the past 2 years) but the API is consistent. For example the users table is now called AspNetUsers in Identity Framework, and the names of several primary key fields kept changing, so the code in several answers will no longer work as-is.

Another problem is that the underlying OWIN access to the database will use a separate context, so changes from separate SQL access can produce invalid results (e.g. not seeing changes made to the database). Again the solution is to work with the supplied API and not try to work-around it.

The correct way to access the current user object in ASP.Net identity (as at this date) is:

var user = UserManager.FindById(User.Identity.GetUserId());

or, if you have an async action, something like:

var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());

FindById requires you have the following using statement so that the non-async UserManager methods are available (they are extension methods for UserManager, so if you do not include this you will only see FindByIdAsync):

using Microsoft.AspNet.Identity;

If you are not in a controller at all (e.g. you are using IOC injection), then the user id is retrieved in full from:

System.Web.HttpContext.Current.User.Identity.GetUserId();

If you are not in the standard Account controller you will need to add the following (as an example) to your controller:

1. Add these two properties:

    /// <summary>
    /// Application DB context
    /// </summary>
    protected ApplicationDbContext ApplicationDbContext { get; set; }

    /// <summary>
    /// User manager - attached to application DB context
    /// </summary>
    protected UserManager<ApplicationUser> UserManager { get; set; }

2. Add this in the Controller's constructor:

    this.ApplicationDbContext = new ApplicationDbContext();
    this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.ApplicationDbContext));

Update March 2015

Note: The most recent update to Identity framework changes one of the underlying classes used for authentication. You can now access it from the Owin Context of the current HttpContent.

ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());

Addendum:

When using EF and Identity Framework with Azure, over a remote database connection (e.g. local host testing to Azure database), you can randomly hit the dreaded "error: 19 - Physical connection is not usable". As the cause is buried away inside Identity Framework, where you cannot add retries (or what appears to be a missing .Include(x->someTable)), you need to implement a custom SqlAzureExecutionStrategy in your project.

这篇关于ASP.NET MVC 5-身份.如何获取当前的ApplicationUser的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆