ASP.NET Core 2.0 MVC自定义数据库初始化程序类上的ObjectDisposedException [英] ObjectDisposedException on a ASP.NET Core 2.0 MVC custom database initializer class

查看:108
本文介绍了ASP.NET Core 2.0 MVC自定义数据库初始化程序类上的ObjectDisposedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自定义数据库初始化类中出现以下异常:

I'm getting the following exception in my custom database initializer class:

发生System.ObjectDisposedException HResult = 0x80131622
Message =无法访问已处置的对象.此错误的常见原因 正在处理从依赖项注入中解决的上下文,并且 然后稍后尝试在您的其他位置使用相同的上下文实例 应用.如果您在 上下文,或将上下文包装在using语句中.如果你是 使用依赖注入,您应该让依赖注入 容器负责处理上下文实例.来源= StackTrace:位于 Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()在 Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() 在Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() 在 Microsoft.EntityFrameworkCore.DbContext.d__48.MoveNext() 在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore 9.<CreateAsync>d__22.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() 在 Microsoft.AspNetCore.Identity.UserManager 1.<CreateAsync>d__73.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() 在 Microsoft.AspNetCore.Identity.UserManager 1.<CreateAsync>d__78.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult() 在E:\ C#中的LlabApp.Data.DbInitializer.d__4.MoveNext() projects \ Atenea \ LlabApp \ LlabApp \ LlabApp \ Data \ DbInitializer.cs:第58行

System.ObjectDisposedException occurred HResult=0x80131622
Message=Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Source= StackTrace: at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed() at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.d__48.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore9.<CreateAsync>d__22.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at Microsoft.AspNetCore.Identity.UserManager1.<CreateAsync>d__73.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at Microsoft.AspNetCore.Identity.UserManager1.<CreateAsync>d__78.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at LlabApp.Data.DbInitializer.d__4.MoveNext() in E:\C# projects\Atenea\LlabApp\LlabApp\LlabApp\Data\DbInitializer.cs:line 58

这是初始化器:

public class DbInitializer : IDbInitializer
{
    private readonly ApplicationDbContext _Context;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<ApplicationRole> _roleManager;

    public DbInitializer(
        ApplicationDbContext context,
        UserManager<ApplicationUser> userManager,
        RoleManager<ApplicationRole> roleManager)
    {
        _context = context;
        _userManager = userManager;
        _roleManager = roleManager;
    }

    public async void Initialize()
    {
        var adminUsers = _userManager.GetUsersInRoleAsync(RoleClaimValues.Admin).Result;
        if (adminUsers == null || adminUsers.Count == 0)
        {
(...)
        }
     }
}

public interface IDbInitializer
{
    void Initialize();
}

这是startup.cs,在其中我在ConfigureService中添加IDbInitializer的范围,然后从Configure调用它:

And here is the startup.cs where i add the scope of IDbInitializer in ConfigureService and then call it from Configure:

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

    public IConfiguration Configuration { get; }


    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("ApplicationConnection")));

        services.AddIdentity<ApplicationUser, ApplicationRole>(o => {
            o.Password.RequireDigit = false;
            o.Password.RequiredLength = 4;
            o.Password.RequireLowercase = false;
            o.Password.RequireUppercase = false;
            o.Password.RequireNonAlphanumeric = false;
            o.User.RequireUniqueEmail = true;
        })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddMvc();

        // Add application services.
        services.AddTransient<IEmailSender, MessageServices>();
        //Seed database
        services.AddScoped<IDbInitializer, DbInitializer>();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IDbInitializer dbInitializer)
    {
        loggerFactory.AddConsole();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();

            app.UseBrowserLink();
            app.UseDatabaseErrorPage();

            app.UseStatusCodePages("text/plain", "Status code page, status code: {0}");
        }
        else
        {
            app.UseExceptionHandler("/Error");
        }

        app.UseStaticFiles();
        app.UseAuthentication();

        dbInitializer.Initialize();

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

我不知道为什么异常告诉我们问题可能出在上下文放置在某个地方.

I don't know why the exception tells that the problem could be that the context is disposed somewhere.

我还添加了

.UseDefaultServiceProvider(options =>
  options.ValidateScopes = false)

.UseStartup<Startup>()之后,以防万一与范围有关,但例外是相同的.

after .UseStartup<Startup>() just in case it was something relative to the scopes, but the exception is the same.

推荐答案

我遇到了与您相同的问题. 您确实必须更改所有代码才能返回Task.否则,DbContext将在所有操作完成之前被处理掉.

I had the same problem as you had. You indeed have to change all code to return a Task. Otherwise the DbContext is disposed before all actions are done.

数据库初始化在dotnet core 2.0中进行了更改.我创建了有关此特定主题的博客. 参见 http://www.locktar.nl/programming/net-core/seed-database-users-roles-dotnet-core-2-0-ef/了解更多信息.

Database Initialization is changed in dotnet core 2.0. I created a blog about this specific topic. See http://www.locktar.nl/programming/net-core/seed-database-users-roles-dotnet-core-2-0-ef/ for more information.

这篇关于ASP.NET Core 2.0 MVC自定义数据库初始化程序类上的ObjectDisposedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆