使用ASP.NET 5/MVC6标识自定义配置文件数据属性

Ole*_*vik 2 c# asp.net-core-mvc

我使用asp.net 5 Web应用程序模板(Mvc6/MVC core/Asp.net-5)制作了一个名为ShoppingList的示例Web应用程序.我想用自定义字段名称DefaultListId扩展用户配置文件.

ApplicationUser.cs:

namespace ShoppingList.Models
{
    // Add profile data for application users by adding properties to the ApplicationUser class
    public class ApplicationUser : IdentityUser
    {
        public int DefaultListId { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

在家庭控制器中,我想访问为此属性存储的数据.我试过了:

namespace ShoppingList.Controllers
{
    public class HomeController : Controller
    {
       private UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

        public IActionResult Index()
        {
           var userId = User.GetUserId();
           ApplicationUser user = userManager.FindById(userId);

            ViewBag.UserId = userId;
            ViewBag.DefaultListId = user.DefaultListId;

            return View();
        }
    //other actions omitted for brevity
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

严重级代码描述项目文件行抑制状态错误CS7036没有给出对应于'UserManager.UserManager所需的形式参数'optionsAccessor'的参数(IUserStore,IOptions,IPasswordHasher,IEnumerable>,IEnumerable>,ILookupNormalizer,IdentityErrorDescriber,IServiceProvider,ILogger >,IHttpContextAccessor)'ShoppingList.DNX 4.5.1,ShoppingList.DNX Core 5.0 C:\ Users\OleKristian\Documents\Programmering\ShoppingList\src\ShoppingList\Controllers\HomeController.cs 15 Active

和...

严重级代码描述项目文件行抑制状态错误CS1061'UserManager'不包含'FindById'的定义,并且没有扩展方法'FindById'接受类型'UserManager'的第一个参数可以找到(你是否缺少using指令或程序集参考?)ShoppingList.DNX 4.5.1,ShoppingList.DNX Core 5.0 C:\ Users\OleKristian\Documents\Programmering\ShoppingList\src\ShoppingList\Controllers\HomeController.cs 20 Active

pok*_*oke 5

你不应该UserManager像往常一样实例化你自己的.实际上很难这样做,因为它要求你向构造函数传递很多参数(而且大多数事情也很难正确设置).

ASP.NET Core广泛使用依赖注入,因此您应该以自动接收用户管理器的方式设置控制器.这样,您不必担心创建用户管理器:

public class HomeController : Controller
{
    private readonly UserManager<ApplicationUser> userManager;

    public HomeController (UserManager<ApplicationUser> userManager)
    {
        this.userManager = userManager;
    }

    // …
}
Run Code Online (Sandbox Code Playgroud)

然而,为了做到这一点,首先需要设置ASP.NET身份来实际了解你ApplicationUser,并使其可用于存储用户的身份.为此,您需要修改Startup该类.在该ConfigureServices方法中,您需要更改AddIdentity调用以使其引用您的实际类型:

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();
Run Code Online (Sandbox Code Playgroud)

IdentityRole这里指的是ASP.NET Identity使用的标准角色类型(因为您不需要自定义角色类型).如您所见,我们还引用了一个ApplicationDbContext实体框架数据库上下文,用于修改后的身份模型; 所以我们也需要设置那个.在你的情况下,它可能看起来像这样:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        // here you could adjust the mapping
    }
}
Run Code Online (Sandbox Code Playgroud)

这将确保ApplicationUser实体实际存储在数据库中.我们差不多完成了,但我们现在只需告诉实体框架这个数据库上下文.因此,在类的ConfigureServices方法中,请Startup确保调整AddEntityFramework调用以设置ApplicationDbContext数据库上下文.如果您有其他数据库上下文,您可以链接这些:

services.AddEntityFramework()
    .AddSqlServer()
    .AddDbContext<IdentityContext>(opts => opts.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]))
    .AddDbContext<DataContext>(opts => opts.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
Run Code Online (Sandbox Code Playgroud)

就是这样!现在,Entity Framework了解新用户实体并将其正确映射到数据库(包括您的新属性),ASP.NET Identity也了解您的用户模型,并将其用于所做的一切,并且您可以UserManager注入进入控制器(或服务,或其他)做东西.


至于你的第二个错误,你得到这个,因为用户管理器没有FindById方法; 它只是一种FindByIdAsync方法.实际上,在ASP.NET Core的许多地方都会看到这种情况,只有异步方法,所以接受它并开始使你的方法异步.

在您的情况下,您需要更改这样的Index方法:

// method is async and returns a Task
public async Task<IActionResult> Index()
{
    var userId = User.GetUserId();

    // call `FindByIdAsync` and await the result
    ApplicationUser user = await userManager.FindByIdAsync(userId);

    ViewBag.UserId = userId;
    ViewBag.DefaultListId = user.DefaultListId;

    return View();
}
Run Code Online (Sandbox Code Playgroud)

如您所见,它不需要很多更改就可以使方法异步.大部分都保持不变.