.NET自定义中间件无法启动且不写入Serilog日志求助
自定义中间件不启动+Serilog日志写入失败的解决方法
1. 修正Logger注入方式
中间件构造函数中使用非泛型ILogger会导致依赖注入容器无法正确解析Logger实例,进而影响中间件初始化。修改为泛型Logger:
public class MyMiddleware { private readonly RequestDelegate _next; private readonly ILogger<MyMiddleware> _logger; // 改为泛型Logger public MyMiddleware(RequestDelegate next, ILogger<MyMiddleware> logger) { _next = next; _logger = logger; } // 其余代码不变 }
2. 调整中间件注册顺序
ASP.NET Core中间件按注册顺序执行,若UseMyMiddleware放置在UseEndpoints等下游中间件之后,会导致无法进入请求管道。正确注册顺序示例:
webBuilder.Configure(app => { // 自定义中间件需放在路由、端点注册之前 app.UseMyMiddleware(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); });
3. 完善Serilog日志配置(测试环境)
- 测试结束手动刷新日志:Serilog默认异步写入,测试进程退出可能导致日志未落地,在NUnit的
TearDown中添加刷新逻辑:
[TearDown] public void TearDown() { Log.CloseAndFlush(); }
- 确认日志路径权限:检查测试输出目录下的
logs文件夹是否存在、是否有写入权限,可临时改用绝对路径测试:
Log.Logger = new LoggerConfiguration() .WriteTo.File(@"C:\temp\logs\log.txt", rollingInterval: RollingInterval.Day) .CreateLogger();
4. 确保测试项目正确触发中间件
直接调用控制器方法不会经过HTTP请求管道,必须使用WebApplicationFactory创建HttpClient发送请求,才能触发中间件执行:
public class CustomWebApplicationFactory : WebApplicationFactory<Program> { protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.ConfigureServices(services => { // 替换为测试用Serilog日志 services.AddLogging(logging => { logging.ClearProviders(); logging.AddSerilog(); }); }); builder.Configure(app => { app.UseMyMiddleware(); }); } } // 测试方法 [Test] public async Task TestMiddlewareExceptionHandling() { var factory = new CustomWebApplicationFactory(); var client = factory.CreateClient(); // 发送请求到会抛出异常的接口 var response = await client.GetAsync("/api/test"); // 验证响应状态码和返回内容 Assert.AreEqual(HttpStatusCode.InternalServerError, response.StatusCode); var errorContent = await response.Content.ReadAsStringAsync(); Assert.That(errorContent, Does.Contain("ErrorId-")); }
5. 排查异常被提前捕获的情况
若项目中注册了UseExceptionHandler等内置异常处理中间件,需确保其在自定义中间件之后注册,否则内置中间件会先捕获异常,导致自定义中间件的catch块无法执行:
webBuilder.Configure(app => { app.UseMyMiddleware(); // 自定义中间件在前 app.UseExceptionHandler("/error"); // 内置异常处理在后 });
内容的提问来源于stack exchange,提问作者PippoBest
相关产品推荐
相关产品推荐

