InvalidOperationException: не удается разрешить определенную службу «Microsoft.AspNetCore.Identity.UserManager .NET Core 2.0 - PullRequest
0 голосов
/ 29 апреля 2018

Обнаружение этой ошибки после обновления .NET Core 1.1

InvalidOperationException: не удается разрешить службу с областью действия 'Microsoft.AspNetCore.Identity.UserManager`1 [Project1.Models.ApplicationUser] от корневого провайдера. Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution (Тип serviceType, ServiceProvider serviceProvider)

Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution (Тип serviceType, ServiceProvider, сервис-провайдер) Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService (Тип Тип Обслуживания) Microsoft.Extensions.Internal.ActivatorUtilities + ConstructorMatcher.CreateInstance (IServiceProvider провайдер) Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance (IServiceProvider провайдер, Type instanceType, Object [] параметры) Microsoft.AspNetCore.Builder.UseMiddlewareExtensions + <> c__DisplayClass4_0.b__0 (RequestDelegate далее) Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build () Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication ()

Startup.cs

public void ConfigureServices(IServiceCollection services) {

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

            services.AddIdentity<ApplicationUser, IdentityRole>(o => {
                // configure identity options
                o.Password.RequireDigit = false;
                o.Password.RequireLowercase = false;
                o.Password.RequireUppercase = false;
                o.Password.RequireNonAlphanumeric = false;
                o.Password.RequiredLength = 6;
            })


  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
            app.UseAuthentication();
        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        var rewriteOptions = new RewriteOptions().AddRedirectToHttps();
        app.UseRewriter(rewriteOptions);

Program.cs

public class Program
    {
        public static void Main(string[] args)
        {
            var host = BuildWebHost(args);

            host.Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
             .UseSetting("detailedErrors", "true")
             .UseStartup<Startup>()
            .Build();
    }

ApplicationDBContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options) {
        }


        public DbSet<UserDevice> UserDevices { get; set; }
        public DbSet<Advertisement> Advertisements { get; set; }


        protected override void OnModelCreating(ModelBuilder builder) {
            base.OnModelCreating(builder);

            builder.Entity<UserDevice>().HasKey(x => new { x.Id, x.DeviceId }); // configure composite key
        }


    }

1 Ответ

0 голосов
/ 30 апреля 2018

Я только что обновил свое приложение с .NET Core 1.x до 2.x, и есть очень подробная документация от Microsoft о том, как перейти с .NET Core 1.x на 2.x. Вы должны следовать инструкциям и убедиться, что вы делаете все шаги, применимые к вашему проекту.

Например, я могу сказать, что ваш Program.cs отличается от того, который создан шаблоном 2.X.

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>

        // You don't need .UseKestrel() and others as they're from 1.X.
        // .CreateDefaultBuilder() already includes them.

        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
}

Так как вы не опубликовали код для ApplicationUser, я могу опубликовать только мой. Поскольку мне нужно изменить первичный ключ со строки по умолчанию на GUID, мне нужно создать пользовательские классы для пользователя и ролей приложения.

public class AppUser : IdentityUser<Guid>
{
    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    public string DisplayName => $"{ this.FirstName } { this.LastName }";
}

public class AppRole : IdentityRole<Guid>
{
}

Затем вам нужно наследовать от IdentityDbContext из AppUser, AppRole и первичного ключа GUID.

public class AppIdentityDbContext : IdentityDbContext<AppUser, AppRole, Guid>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<AppUser>().ToTable("User");
        builder.Entity<AppRole>().ToTable("Role");

        builder.Entity<IdentityUserRole<Guid>>().ToTable("UserRole");
        builder.Entity<IdentityUserClaim<Guid>>().ToTable("UserClaim");
        builder.Entity<IdentityRoleClaim<Guid>>().ToTable("RoleClaim");
        builder.Entity<IdentityUserLogin<Guid>>().ToTable("UserLogin");
        builder.Entity<IdentityUserToken<Guid>>().ToTable("UserToken");
    }
}

В вызове ConfigureServices вы пропускаете .AddEntityFrameworkStores() и .AddDefaultTokenProviders().

services.AddIdentity<AppUser, AppRole>(o => {
    // configure identity options
    o.Password.RequireDigit = false;
    o.Password.RequireLowercase = false;
    o.Password.RequireUppercase = false;
    o.Password.RequireNonAlphanumeric = false;
    o.Password.RequiredLength = 6;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
// Components that generate the confirm email and reset password tokens
.AddDefaultTokenProviders();
...