【问题标题】:InvalidOperationException: A key cannot be configured on 'ApplicationUser' because it is a derived typeInvalidOperationException:无法在“ApplicationUser”上配置密钥,因为它是派生类型
【发布时间】:2019-07-12 20:55:00
【问题描述】:

当我创建一个帐户时,它可以正常工作,没有错误,并且注销工作正常。但是当我尝试重新登录时出现此错误:

“无法为 'IdentityUser' 创建 DbSet,因为此类型未包含在上下文模型中。”

我忽略了它,因为我想做一些其他的事情。当我使用播种方法添加 UserRoles 时,它首先运行良好,我猜,没有收到任何错误。但是当我登录时,我得到了下一个错误:

“InvalidOperationException:无法在“ApplicationUser”上配置密钥,因为它是派生类型。必须在根类型“IdentityUser”上配置密钥。如果您不打算将“IdentityUser”包含在模型中,请确保它不包含在上下文的 DbSet 属性中、在对 ModelBuilder 的配置调用中引用或从模型中包含的类型的导航属性中引用。"

我删除了旧数据库并删除了迁移。当我尝试添加迁移(添加迁移用户)时,出现下一个错误: “无法在 'ApplicationUser' 上配置密钥,因为它是派生类型。必须在根类型 'IdentityUser' 上配置密钥。如果您不打算将 'IdentityUser' 包含在模型中,请确保它是未包含在上下文的 DbSet 属性中、在对 ModelBuilder 的配置调用中引用或从模型中包含的类型的导航属性中引用。"

我正在尝试添加自定义身份和用户角色,我遵循了一个关于如何将自定义数据添加到您的身份用户的教程,一位老师给了我们一个关于如何添加用户角色的教程。

我是初学者,使用 .net core 2.2 mvc 和个人用户帐户。

ApplicationDbContext.cs:

using System;
using System.Collections.Generic;
using System.Text;
using application.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace application.Data
{
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        public virtual DbSet<IdentityUser> ApplicationUser {get; set;}
        public new DbSet<application.Models.Update> Update { get; set; }
    }
}

种子.cs:

using System;
using System.Collections.Generic;
using System.Text;
using application.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace application.Data
{
    public class Seed
    {
        public static void SeedUsers(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
        {
            if (roleManager.FindByNameAsync("Admin").Result == null)
            {
                IdentityRole role = new IdentityRole { Name = "Admin" };
                roleManager.CreateAsync(role).Wait();
            }

            if (userManager.FindByEmailAsync("admin@admin.com").Result == null)
            {
                ApplicationUser user = new ApplicationUser
                {
                    FirsName    = "Admin",
                    LastName    = "Admin", 
                    Email       = "admin@admin.com"
                };

                IdentityResult result = userManager.CreateAsync(user, "AdminTest420").Result;

                if (result.Succeeded)
                {
                    userManager.AddToRoleAsync(user, "Admin").Wait();
                }
            }
        }
    }
}

ApplicationUser.cs:

using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace application.Models
{
    public class ApplicationUser : IdentityUser
    {
        public string FirsName { get; set; }
        public string LastName { get; set; }
    }
}

StartUp.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using application.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using application.Models;

namespace application
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddDefaultIdentity<IdentityUser>()
                .AddDefaultUI(UIFramework.Bootstrap4)
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityCore<ApplicationUser>()
                .AddRoles<IdentityRole>()
                .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders()
                .AddDefaultUI();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();


            app.UseAuthentication();
            //Seed.SeedUsers(userManager, roleManager);

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                  name: "Admin",
                  template: "{area:exists}/{controller=AdminHome}/{action=Index}/{id?}");
            });
        }
    }
}

【问题讨论】:

    标签: asp.net .net asp.net-mvc asp.net-core


    【解决方案1】:

    我通过将 IdentityUser 的所有用法替换为 ApplicationUser 解决了同样的问题。在 ApplicationUser 继承 IdentityUser 之后,您应该在代码中的任何地方使用 ApplicationUser。只要确保你没有在你的类或视图中引用 IdentityUser 。

    其实你不需要这一行

    public virtual DbSet<IdentityUser> ApplicationUser {get; set;}
    

    请阅读这篇文章custome user data

    您可以通过 DI 访问AplicationUser

    public class MyController : Controller
        {
            private readonly UserManager<ApplicationUser> _userManager;
    
            public MyController(
                UserManager<ApplicationUser> userManager)
            {
                _userManager = userManager;
            }
    
    

    【讨论】:

      【解决方案2】:

      您的问题是由public virtual DbSet&lt;IdentityUser&gt; ApplicationUser {get; set;} 引起的。

      对于ApplicationUser,您可以通过_context.Users 访问AspNetUsers 表。

      如需自定义身份,请关注Identity model customization in ASP.NET Core

      【讨论】:

        猜你喜欢
        • 2021-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-22
        相关资源
        最近更新 更多