ASP。NET MVC 5 -身份。如何获取当前的ApplicationUser

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

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

我试着这样做:

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

但我得到了以下异常:

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

348748 次浏览

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

正确的代码:

using Microsoft.AspNet.Identity;




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

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

这引入了一种新的依赖关系,对于初学者来说有一个额外的上下文,但是向前发展,用户数据库表发生了变化(在过去2年里发生了3次),但API是一致的。例如,在身份框架中,users表现在被称为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 Context中访问它。

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 - __abc0

和…Ellbar的代码:

2 - string currentUserId = User.Identity.GetUserId(); ApplicationUser currentUser = db.Users。FirstOrDefault (x =比;x.Id == currentUserId);

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

现在asp。MVC项目模板创建一个帐户控制器,以这种方式获取用户管理器:

HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>()

以下是我的工作:

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

对于MVC 5,只需在WebApplication模板脚手架中查看ManageController的EnableTwoFactorAuthentication方法,它是在那里完成的:

        [HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EnableTwoFactorAuthentication()
{
await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", "Manage");
}

答案就在那里,正如微软自己所建议的:

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

它将拥有您在ApplicationUser类中定义的所有附加属性。

截至ASP。NET Identity 3.0.0,这已经被重构成

//returns the userid claim value if present, otherwise returns null
User.GetUserId();
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
ApplicationUser currentUser = UserManager.FindById(User.Identity.GetUserId());


string ID = currentUser.Id;
string Email = currentUser.Email;
string Username = currentUser.UserName;

我成功地获得应用程序用户遵循一段代码

var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var user = manager.FindById(User.Identity.GetUserId());
ApplicationUser EmpUser = user;

如果有人在web forms中使用Identity用户,我通过这样做让它工作:

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

有一个简单的方法:

User.Identity.Name

它提供当前用户的Id。