You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:35:54