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

Posted

技术标签:

【中文标题】ASP.NET MVC 5 - 身份。如何获取当前的ApplicationUser【英文标题】:ASP.NET MVC 5 - Identity. How to get current ApplicationUser 【发布时间】:2014-01-22 10:21:40 【问题描述】:

我的项目中有一个 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.String GetUserId(System.Security.Principal.IIdentity)”方法,并且该方法无法转换为存储表达式。 来源=实体框架

【问题讨论】:

【参考方案1】:

您应该不需要直接在数据库中查询当前的 ApplicationUser。

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

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

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

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();

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

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());

附录:

在 Azure 中使用 EF 和 Identity Framework 时,通过远程数据库连接(例如,本地主机测试到 Azure 数据库),您可能会随机遇到可怕的“错误:19 - 物理连接不可用”。由于原因隐藏在 Identity Framework 中,您无法在其中添加重试(或似乎缺少 .Include(x-&gt;someTable)),因此您需要在项目中实现自定义 SqlAzureExecutionStrategy

【讨论】:

@TBA - 谢谢,我后来意识到这是一种扩展方法。需要添加 Microsoft.AspNet.Identity 使用 .再次感谢 找不到类型或命名空间 UserStore。我使用 Microsft.AspNet.Indentity 添加 @Zapnologica:这听起来像是一个新问题(建议你发布它)。您可以并行扩展ApplicationUser 类(特定于应用程序)和AspNetUsers 表,它们将提供任何新字段。再说一遍:不要直接打数据库! :) @LifeH2O:FindById 返回的 ApplicationUser 是 your 类,带有 your 额外属性。请尝试一下。 等待您的新解决方法:P【参考方案2】:

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

正确代码:

using Microsoft.AspNet.Identity;


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

【讨论】:

User.Identiy.GetUserId 对我来说不存在。那是我自定义的方法吗?我只起身 User.Identity 没关系...您需要“使用 Microsoft.AspNet.Identity;”让那个方法在那里。 请注意,用户对象仅在控制器中可见。 您当然应该使用UserManager 方法而不是直接访问数据库吗? @Josh Bjelovuk:当 API 可用时,切勿直接访问数据库。这为初学者引入了一个新的依赖关系,即为初学者提供额外的上下文,但未来用户数据库表会发生变化(过去 2 年中发生了 3 次),但 API 是一致的。【参考方案3】:

它在答案的 cmets 中,但没有人将此作为实际解决方案发布。

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

using Microsoft.AspNet.Identity;

【讨论】:

我带着那个例外来到这里,我用那个using解决了它。看到有 15,000 人访问了这个问题,我认为这是一个有用的答案:) @TrueBlueAussie,尽管不是对 OPs 问题的直接回答,但我觉得提到 using 是一个非常有用的补充。 为了清楚起见,这是因为.GetUserId()是一种扩展方法【参考方案4】:

Ellbar 的代码有效!您只需添加 using。

1 - using Microsoft.AspNet.Identity;

还有……Ellbar的代码:

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

使用此代码(在 currentUser 中),您可以处理连接用户的一般数据,如果您需要额外数据...请参阅 this link

【讨论】:

它可能“工作”,但肯定不建议绕过提供的 API 并直接访问数据库 如果您确实使用了该 API,则不需要额外的工作来获取额外的数据因为它已经在 ApplicationUser 对象中 我同意!但是,之所以采用这种方式,是因为我今天已经有一个系统,在数据库中运行,我需要一个简单的解决方案来解决这个问题!当然,在早期的系统中,我会将对象放在适当的类和标识中。【参考方案5】:

从 ASP.NET Identity 3.0.0 开始,这已被重构为

//returns the userid claim value if present, otherwise returns null
User.GetUserId();

【讨论】:

【参考方案6】:
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;

【讨论】:

【参考方案7】:

对于 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 类中定义的所有附加属性。

【讨论】:

已经涵盖。请检查是否尚未发布相同的答案(或对现有答案添加评论):)【参考方案8】:

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

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

以下对我有用:

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

【讨论】:

【参考方案9】:

如果有人在web forms 中与Identity 用户合作,我会这样做:

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

【讨论】:

【参考方案10】:

我通过以下代码成功获得应用程序用户

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

【讨论】:

以上是关于ASP.NET MVC 5 - 身份。如何获取当前的ApplicationUser的主要内容,如果未能解决你的问题,请参考以下文章

ASP.Net MVC 5 身份验证与另一个 MVC 5 身份网站

如何在asp.net mvc 5身份中的授权属性中使用动态角色

如何在 ASP.NET MVC 5 中实现自定义身份验证

如何使用 ASP.NET 5 MVC 6 保护 Web API

如何在 ASP.NET MVC 5.2.3 和 Katana 中正确设置双重身份验证?

ASP.NET MVC 5 中的基本身份验证