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

在旧的会员机制中,这很简单,但在新的身份方法中,我不知道如何做到这一点。

我试着这样做:

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

但我得到了以下异常:

LINQ to Entities不识别方法System。字符串GetUserId(System.Security.Principal.IIdentity)方法,该方法不能转换为存储表达式。 源= EntityFramework


当前回答

如果有人在web表单中使用身份用户,我通过这样做得到了它的工作:

var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = manager.FindById(User.Identity.GetUserId());

其他回答

我的错误,我不应该在LINQ查询中使用方法。

正确的代码:

using Microsoft.AspNet.Identity;


string currentUserId = User.Identity.GetUserId();
ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);

如果有人在web表单中使用身份用户,我通过这样做得到了它的工作:

var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = manager.FindById(User.Identity.GetUserId());

您不需要直接查询数据库以查找当前的ApplicationUser。

这引入了一种新的依赖关系,对于初学者来说有一个额外的上下文,但是向前发展,用户数据库表发生了变化(在过去2年里发生了3次),但API是一致的。例如,用户表现在在身份框架中被称为AspNetUsers,几个主键字段的名称一直在变化,所以几个答案中的代码将不再像以前那样工作。

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

在ASP中访问当前用户对象的正确方法。净身份(截至目前)为:

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

或者,如果你有一个异步动作,像这样:

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

FindById要求你有下面的using语句,这样非异步的UserManager方法是可用的(它们是UserManager的扩展方法,所以如果你不包括这个,你只会看到FindByIdAsync):

using Microsoft.AspNet.Identity;

如果你根本不在控制器中(例如,你正在使用IOC注入),那么用户id将从:

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

如果你不在标准的Account控制器中,你需要在你的控制器中添加以下内容(作为示例):

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月更新

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

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

附录:

当在Azure中使用EF和Identity Framework时,通过远程数据库连接(例如,本地主机测试到Azure数据库),你可以随机点击可怕的“错误:19 -物理连接不可用”。由于原因被隐藏在身份框架中,在那里你不能添加重试(或似乎是一个丢失的. include (x->someTable)),你需要在你的项目中实现一个自定义SqlAzureExecutionStrategy。

它在答案的评论中,但没有人把它作为实际的解决方案。

你只需要在顶部添加一个using语句:

using Microsoft.AspNet.Identity;

Ellbar的代码起作用了!你只需要加上using。

1 -使用Microsoft.AspNet.Identity;

和…Ellbar的代码:

2 - 字符串 currentUserId = User.Identity.GetUserId(); 应用程序用户当前用户 = db。Users.FirstOrDefault(x => x.Id == currentUserId);

使用这段代码(在currentUser中),您可以处理连接用户的一般数据,如果您需要额外的数据…请看这个链接