简体   繁体   English

无法访问已处置的 object Asp.net Identity Core

[英]Cannot access a disposed object Asp.net Identity Core

I am getting this error我收到这个错误

System.ObjectDisposedException
  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=Microsoft.EntityFrameworkCore
  StackTrace:
   at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.AsyncDisposer.Dispose()
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<ExecuteSingletonAsyncQuery>d__21`1.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.UserManager`1.<FindByNameAsync>d__78.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.UserValidator`1.<ValidateUserName>d__6.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Identity.UserValidator`1.<ValidateAsync>d__5.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.UserManager`1.<ValidateUserAsync>d__172.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.UserManager`1.<CreateAsync>d__74.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.UserManager`1.<CreateAsync>d__79.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at EmployeeController.<Create>d__3.MoveNext() in Controllers\EmployeeController.cs:line 31

For the following code对于以下代码

public class EmployeeController : Controller
{
    private readonly UserManager<Employee> userManager;
    public EmployeeController(UserManager<Employee> userManager)
    {
        this.userManager = userManager;
    }

    public ActionResult<string> Get()
    {
        return "Test Employee";
    }

    [HttpPost("Create")]
    public async void Create([FromBody]string employee)
    {
        var user = new Employee { UserName = "test@gmail.com", Email = "test@gmail.com" };
        var d = await userManager.CreateAsync(user, "1234567");
    }
}

Startup.cs启动.cs

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.AddDbContext<ApplicationDbContext>(options =>
         options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<Employee, IdentityRole>(opts =>
       {
           opts.Password.RequireDigit = false;
           opts.Password.RequireLowercase = false;
           opts.Password.RequireUppercase = false;
           opts.Password.RequireNonAlphanumeric = false;
           opts.Password.RequiredLength = 7;
           opts.User.RequireUniqueEmail = true;

       }).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

        services.AddAuthentication(opts =>
        {
            opts.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(cfg =>
        {
            cfg.RequireHttpsMetadata = false;
            cfg.SaveToken = true;
            cfg.TokenValidationParameters = new TokenValidationParameters()
            {
                // standard configuration
                ValidIssuer = Configuration["Auth:Jwt:Issuer"],
                ValidAudience = Configuration["Auth:Jwt:Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(Configuration["Auth:Jwt:Key"])),
                ClockSkew = TimeSpan.Zero,

                // security switches
                RequireExpirationTime = true,
                ValidateIssuer = true,
                ValidateIssuerSigningKey = true,
                ValidateAudience = true
            };
        });


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

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseAuthentication();
        app.UseMvc();
    }
}

Do I need to register something into my DI?我需要在我的 DI 中注册一些东西吗? I was under the impression that AddEntityFrameworkStores<ApplicationDbContext>() would be enough.我的印象是AddEntityFrameworkStores<ApplicationDbContext>()就足够了。

You are an async void victim: 你是一个async void受害者:

[HttpPost("Create")]
public async void Create([FromBody]string employee)
{
    var user = new Employee { UserName = "test@gmail.com", Email = "test@gmail.com" };
    var d = await userManager.CreateAsync(user, "1234567");
}

You are dispatching an asynchronous operation that is not being awaited, and the context will be disposed before the await context.SaveChangesAsync() in CreateAsync . 您正在调度等待的异步操作,并且上下文将在CreateAsyncawait context.SaveChangesAsync()之前CreateAsync

Fast, obvious solution: 快速,明显的解决方案

[HttpPost("Create")]
public async Task Create([FromBody]string employee)
{
    var user = new Employee { UserName = "test@gmail.com", Email = "test@gmail.com" };
    var d = await userManager.CreateAsync(user, "1234567");
}

However, you should always return IActionResult from an Action. 但是,您应始终从Action返回IActionResult That makes it easier to change the response code as well as show your intent: 这样可以更轻松地更改响应代码并显示您的意图:

[HttpPost("Create")]
public async Task<IActionResult> Create([FromBody]string employee)
{
    var user = new Employee { UserName = "test@gmail.com", Email = "test@gmail.com" };
    var d = await userManager.CreateAsync(user, "1234567");

    if (d == IdentityResult.Success)
    {
        return Ok();
    }
    else 
    {
        return BadRequest(d);
    }
}

I had same problem, I forgot add 2 row in my StartUp.cs:我有同样的问题,我忘记在我的 StartUp.cs 中添加 2 行:

services.AddScoped<UserManager, UserManager>(); services.AddScoped<UserManager, UserManager>();
services.AddScoped<RoleManager, RoleManager>(); services.AddScoped<RoleManager, RoleManager>();

Add it, it will work normally!添加它,它会正常工作!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法访问ASP.NET Core后台服务中的已处置对象 - Cannot access a disposed object in ASP.NET Core background service 如何解决asp.net core 2.1中无法访问已处置对象? - How to solve Cannot access a disposed object in asp.net core 2.1? 无法访问已处理的对象。此错误的原因 - 与依赖注入相关的 Asp.net Core 异常 - Cannot access a disposed object.cause of this error - Asp.net Core Exception related to Dependency Injection 注入 DbContext 时无法访问 ASP.NET Core 中已处理的对象 - Cannot access a disposed object in ASP.NET Core when injecting DbContext 在ASP.NET Core授权属性中将存储库与DbContext一起使用:“无法访问已处置的对象” - Use repository with DbContext in ASP.NET Core Authorize-Attribute: “Cannot access a disposed object” System.ObjectDisposedException:无法访问已处理的对象,ASP.NET Core 3.1 - System.ObjectDisposedException: Cannot access a disposed object, ASP.NET Core 3.1 C#:使用 IQueryable 注入 DbContext 时,无法访问 ASP.NET 核心中已处置的 object - C#: Cannot access a disposed object in ASP.NET Core when injecting DbContext with IQueryable Asp.net Core:无法访问已处置的对象(不同的错误) - Asp.net Core: Can not access a disposed object (different errors) 无法访问已处理的对象 Datacontext asp.net 5 - cannot access a disposed object Datacontext asp.net 5 .NET Core SocketIO-无法访问已处置的对象 - .NET Core SocketIO - Cannot access disposed object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM