ASP.net身份验证:如何获取当前的IdentityUser(ApplicationUser)?UserManager.FindById在哪里?

7
我从VS2013中使用默认的ASP.net模板开始。我想获取当前用户对象,这应该可以在不直接访问数据库的情况下实现。
在文档中,这看起来非常简单:http://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspx 所以它应该是:
var currentUser = manager.FindById(User.Identity.GetUserId()); 

但是FindById方法不见了!几个小时以来,我一直在尝试使用FindByIdAsync代替。但我认为我遇到了死锁。

public class UserManager : UserManager<IdentityUser>
{
    public UserManager()
        : base(new UserStore<IdentityUser>(new ApplicationDbContext()))
    {
    }

    public async System.Threading.Tasks.Task<IdentityUser> GetCurrentUser()
    {
        var user = await FindByIdAsync(HttpContext.Current.User.Identity.Name);
        return user;
    }
}

调用属性(The calling property):
private IdentityUser_CurrentUser;
protected IdentityUser CurrentUser
{
    get
    {
        if (_CurrentUser == null)
        {                   
            var manager = new UserManager();
            var result = manager.GetCurrentUser();
            //-- STOPS HERE!!
            _CurrentUser = result.Result;
        }
        return _CurrentUser;
    }
}

任何帮助都将不胜感激!无论是告诉我FindById去哪了,还是如何让我的代码工作。或者有没有其他加载IdentityUser的方法?

补充

在用户管理器中,FindById未找到,但可以找到this.FindById。我会添加截图。这不是一个合适的解决方案,因为我不明白为什么会发生这种情况,有没有人能解释一下这种行为?我附上两个打开智能提示的屏幕截图。我还想提到的是,这不是智能提示的问题-如果我不加this.,代码就无法编译。

输入“Fi”后智能提示的屏幕截图:

Intellisense open with Fi

输入“this.Fi”后智能提示的屏幕截图:

Intellisense open with this.Fi

这样至少我不再被卡住了。


1
不确定这是否相关,但是class UserManager : UserManager<IdentityUser>总是让我感到困惑。为什么不使用class MyUserManager : UserManager<IdentityUser> - tschmit007
什么类的调用属性?您是否尝试直接从控制器使用管理器实例化代码,如var manager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(context));,然后使用FindByIdAsync?UserManager怎么可能知道HttpContext这样的东西? - tschmit007
我没有使用MVC写代码。这是一个Web Forms应用程序。你说的“直接从控制器”是什么意思?听起来像是MVC。调用在我的主页面的代码后面进行。我尽量简化了代码,所以最终的代码不是很美观... - Tillito
1
我认为我的块与此有关:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html 但是将整个主页面标记为异步仅仅是为了读取用户对象,这似乎不太合适。 - Tillito
1
我认为你已经找到了问题所在。我只是补充一下,最新的ASP MVC(官方)模板在AccountController中使用async方法,当该方法使用await时。 - tschmit007
显示剩余3条评论
1个回答

14
FindById是来自Microsoft.AspNet.Identity.UserManagerExtensions类的扩展方法。它是Microsoft.AspNet.Identity.Core nuget包的一部分。

您应该添加

using Microsoft.AspNet.Identity;

为了开始使用非异步方法,您需要对代码进行修改。


2
此外,使用 Visual Studio 2013 Update 3 及更高版本,只需创建一个带有个人账户的新 MVC 项目,您就可以看到许多使用 FindById 的用例。 - RickAndMSFT
命名空间已经包含在内。这些是我的命名空间:using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Owin.Security; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity; System.Web; - Tillito
正如我在问题中提到的,这是一个ASP.net Web Forms项目,不是MVC。但我认为我找到了解决方案。我将编辑我的问题。 - Tillito
谢谢Rick,这帮助我看到如何正确使用它。 ApplicationDbContext applicationDbContext = new ApplicationDbContext(); UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(applicationDbContext)); var user = userManager.FindById<ApplicationUser>(Context.User.Identity.GetUserId()); - Ronen Festinger
前面的评论存在一些问题,即ApplicationUser的子自定义对象无法加载。这是更好的代码: private static ApplicationUserManager _userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); var user = _userManager.FindByName<ApplicationUser, string>(userName); - Ronen Festinger
实际上,静态方法不太好用,因为它不会更新,你应该使用以下代码:private ApplicationUserManager _userManager { get { return HttpContext.GetOwinContext().GetUserManager(); } } - Ronen Festinger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接