c# - 无法访问已处置的对象。对象名称:AspNet Core/EF Core 项目中的“IServiceProvider”错误
问题描述
我正在使用 Entity Framework Core 编写一个 ASP.NET Core 应用程序。我也在使用 MediatR。
当我触发数据库更新时,无论是保存还是删除,都会出现以下错误:
无法访问已处置的对象。对象名称:'IServiceProvider'
它有时会在第一次尝试时发生,有时会在后续尝试中发生。我似乎找不到模式。我确实设法做的是在调用的处理程序中打断点,await _applicationDbContext.SaveChangesAsync(cancellationToken);
尽管错误实际上是在控制器中抛出的,on await _mediator.Send(someRequestModel);
. 引发错误后,应用程序进入中断模式并崩溃。
我将使用虚拟名称,但我认为这是相关代码:
控制器:
public MyController(IMediator mediator)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
}
[HttpDelete("{id}")]
public async void Delete(string id)
{
await _mediator.Send(new DeleteRequestModel(Guid.Parse(id))); // error thrown here
}
处理程序:
public class DeleteCommandHandler : IRequestHandler<DeleteRequestModel>
{
private readonly ApplicationDbContext _applicationDbContext;
public DeleteCommandHandler(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public async Task<Unit> Handle(DeleteRequestModel request, CancellationToken cancellationToken)
{
var item = _applicationDbContext.MyData.First(x => x.Id == request.Id);
_applicationDbContext.MyData.Remove(item);
await _applicationDbContext.SaveChangesAsync(cancellationToken); // pretty sure this errors out
return Unit.Value;
}
}
启动.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnectionString")));
services.AddDbContext<ApplicationAspNetUsersDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnectionString")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationAspNetUsersDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationAspNetUsersDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllers();
services.AddRazorPages();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; });
services.AddSwaggerDocument();
services.AddMediatR(AppDomain.CurrentDomain.Load("MySolution.MyProject.EntityFramework"));
services.AddValidatorsFromAssembly(AppDomain.CurrentDomain.Load("MySolution.MyProject"));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidatorPipelineBehavior<,>));
services.AddSingleton(x =>
new BlobServiceClient(Configuration.GetConnectionString("AzureBlobStorageConnection")));
services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_CONNECTIONSTRING"]);
services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
services.Configure<AzureBlobStorage>(Configuration.GetSection("AzureBlobStorage"));
services.Configure<ApplicationInsights>(Configuration.GetSection("ApplicationInsights"));
}
最后,这是堆栈跟踪,这次是更新操作:
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.GetActionsForException(Type exceptionType, TRequest request, MethodInfo& actionMethodInfo)
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.<Handle>d__2.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MediatR.Pipeline.RequestPostProcessorBehavior`2.<Handle>d__2.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MediatR.Pipeline.RequestPreProcessorBehavior`2.<Handle>d__2.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MySolution.Web.Controllers.MyController.< Patch >d__7.MoveNext() in
..\Controllers\MyController.cs:line 85
任何帮助是极大的赞赏。
解决方案
您在控制器中使用 async void。Async void 应该只在特定场景中使用,在这种情况下,您应该使用 Task 作为返回类型。
推荐阅读
- javascript - AngularJS更新元素仅在其属性之一发生更改时才有效
- docker - Asp.net 核心网站未在 docker 中运行
- linux - 如何从命令行隐藏 curl 参数?
- ios - 从 App Store 下载的 App 崩溃,TestFlight 运行良好
- apache - repo.maven.apache.org 的 Nexus 代理不起作用
- javascript - Angular 5 应用程序无法在 Safari 移动浏览器中呈现
- android - 简单的 Firebase Auth UI 检查和应用程序崩溃
- python - Matplotlib AttributeError:模块“matplotlib.cbook”没有属性“_define_aliases”
- login - google user_id 可以改吗?
- html - 为什么“a@a”会通过电子邮件输入的内置验证?