首页 文章

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

提问于
浏览
218

我的项目中有一个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)'方法,并且此方法无法转换为商店表达式 . 来源=的EntityFramework

10 回答

  • 6

    您不需要直接查询数据库以获取当前的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));
    

    Update March 2015

    注意: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 .

  • 29
    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;
    
  • 1

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

    正确的代码:

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

    它在答案的评论中,但没有人发布这个作为实际的解决方案 .

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

    using Microsoft.AspNet.Identity;
    
  • 9

    对于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类中定义的所有其他属性 .

  • 5

    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

  • 0

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

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

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

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

    以下为我工作:

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

    如果有人在 web forms 中使用 Identity 用户,我通过这样做得到了它:

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

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

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

相关问题