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

时间:2014-01-04 19:40:56

标签: c# asp.net-mvc-5 identity asp.net-identity

我的项目中有一个Article实体,其中ApplicationUser属性名为Author。如何获取当前记录的ApplicationUser的完整对象?在创建新文章时,我必须将Author中的Article属性设置为当前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)'方法,并且此方法无法转换为商店表达式。     源=的EntityFramework

10 个答案:

答案 0 :(得分:429)

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

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

另一个问题是对数据库的基础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月更新

注意: Identity Framework的最新更新会更改用于身份验证的基础类之一。您现在可以从当前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 - 物理连接不可用”。由于原因被隐藏在Identity Framework中,您无法在其中添加重试(或似乎缺少.Include(x->someTable)),您需要在项目中实现自定义SqlAzureExecutionStrategy

答案 1 :(得分:58)

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

正确的代码:

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

答案 2 :(得分:31)

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

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

using Microsoft.AspNet.Identity;

答案 3 :(得分:10)

Ellbar的代码有效!您只需要添加使用。

1 - using Microsoft.AspNet.Identity;

而且...... Ellbar的代码:

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

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

答案 4 :(得分:6)

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

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

答案 5 :(得分:5)

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;

答案 6 :(得分:3)

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

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

以下适用于我:

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

答案 7 :(得分:2)

对于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 :(得分:0)

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

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

答案 9 :(得分:0)

如果有人正在与Identity中的web forms个用户一起工作,我可以这样做:

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