在请求管道中写入数据库时遭遇ObjectDisposedException异常
Hey, let's break down this error and fix it! That ObjectDisposedException is popping up because the DbContext instance you're using in your Configure method's middleware is being disposed before you're done using it. Here's the root cause and actionable fixes:
为什么会出现这个错误?
By default, DbContext in ASP.NET Core is registered with a Scoped lifecycle—meaning one instance per request. When you directly inject or use a DbContext in the Configure method, you're likely grabbing a root-scope instance (not tied to the current request). This instance might get disposed early, or it won't align with the request's lifecycle, leading to the "Cannot access a disposed object" error when you try to use it during request processing.
解决方案1:使用自定义中间件(推荐)
Create a dedicated middleware class that gets the DbContext injected via its InvokeAsync method—this ensures you're using a request-scoped instance that stays alive for the duration of the request.
Step 1: 定义中间件类
public class RequestDateTimeLoggingMiddleware { private readonly RequestDelegate _next; public RequestDateTimeLoggingMiddleware(RequestDelegate next) { _next = next; } // DbContext is injected here, tied to the current request's scope public async Task InvokeAsync(HttpContext context, YourDbContext dbContext) { // 执行你的逻辑:保存DateTime到数据库 dbContext.RequestLogs.Add(new RequestLog { RequestTimestamp = DateTime.UtcNow, Path = context.Request.Path }); await dbContext.SaveChangesAsync(); // 继续传递请求到下一个中间件 await _next(context); } }
Step 2: 在Configure中注册中间件
In your Startup.cs (or Program.cs if using top-level statements):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ...其他中间件配置(比如app.UseRouting(), app.UseAuthorization()等) // 添加你的自定义中间件 app.UseMiddleware<RequestDateTimeLoggingMiddleware>(); // ...其他中间件 }
解决方案2:在Configure中手动创建作用域
If you prefer to keep the logic inline in the Configure method, use IServiceScopeFactory to create a request-scoped DbContext instance manually:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceScopeFactory serviceScopeFactory) { // ...其他中间件配置 app.Use(async (context, next) => { // 创建一个作用域,确保DbContext属于当前请求 using (var scope = serviceScopeFactory.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>(); // 执行保存逻辑 dbContext.RequestLogs.Add(new RequestLog { RequestTimestamp = DateTime.UtcNow }); await dbContext.SaveChangesAsync(); } // 继续处理请求 await next(); }); // ...其他中间件 }
额外注意事项
- Double-check that your DbContext is registered as Scoped (this is the default when using
AddDbContext):services.AddDbContext<YourDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); - Avoid using root-scope services (like directly injecting DbContext into
Configure) for request-specific logic—they're not designed to handle per-request operations safely.
内容的提问来源于stack exchange,提问作者Guerrilla

