1

尝试构建一个中间件来记录每个请求的信息。ASP.NET Core 3.1 学习一些基础知识

我试图理解一些奇怪的行为。这是我的中间件构造函数:

public ContextRequestLoggingMiddleware( RequestDelegate next, ILoggerFactory loggerFactory ) {
    this._next = next;
    _logger = loggerFactory.CreateLogger( "ContextRequestLoggingMiddleware" );            
}

使用它按预期工作。每个请求都会记录消息:

public async Task InvokeAsync (HttpContext context ) {
    _logger.LogInformation( "test from middleware" );
    await _next( context );    
}

当我使用下面的代码时:

_logger = loggerFactory.CreateLogger<ContextRequestLoggingMiddleware>();

执行结束,_logger.LogInformation但似乎没有执行,没有记录,没有错误,没有问题,只是跳转到下一行代码。用 WatchList 查看 _logger 我看不出这两种方法有什么区别。

没有记录任何内容的相同行为,如果我使用也不会遇到错误ILogger<T>

public ContextRequestLoggingMiddleware( RequestDelegate next, 
    ILogger<ContextRequestLoggingMiddleware> logger ) {
    this._next = next;
    _logger = logger;
}

我无法注入纯文本ILogger,因为它会引发运行时错误:

尝试激活“Microsoft.AspNetCore.Builder.ContextRequestLoggingMiddleware”时无法解析“Microsoft.Extensions.Logging.ILogger”类型的服务。

再次检查对象,我看不到我使用的不同方法之间的区别。那么这是为什么呢?我会认为ILogger<T>是最佳选择,但为什么它在这里不起作用?它在 Controller 中对我有用。谢谢你的解释。

对于上下文,我的CreateHostBuilder

public static IHostBuilder CreateHostBuilder( string[] args ) =>
    Host.CreateDefaultBuilder( args )
        .ConfigureLogging( ( hostContext, loggingBuilder ) => {
            loggingBuilder.ClearProviders();
            loggingBuilder.AddConfiguration( hostContext.Configuration.GetSection( "Logging" ) );
            loggingBuilder.AddCustomFileLogger();
        }
        ).ConfigureWebHostDefaults( webBuilder => {
            webBuilder.UseStartup<Startup>();
        } );

我的Startup课的一部分:

public void ConfigureServices( IServiceCollection services ) {
    services.AddControllers();
    services.AddDbContext<NPAContext>( options =>
         options.UseSqlServer( Configuration.GetConnectionString( cnnDB ) ) );
    services.AddAuthentication( options => {
        options.DefaultAuthenticateScheme = ApiKeyAuthenticationOptions.DefaultScheme;
        options.DefaultChallengeScheme = ApiKeyAuthenticationOptions.DefaultScheme;
    } )
        .AddApiKeySupport( options => { } );
    
    services.AddSingleton<List<JobEventDTO>>();            
}

public void Configure( IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory ) {
    if ( env.IsDevelopment() ) {
        app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseContextRequestLoggingMiddleware();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints( endpoints => {
        endpoints.MapControllers();
    } );
}

编辑 解决方案:我犯了一个错误,在构建类时ContextRequestLoggingMiddleware我将它放在 NameSpace 下Microsoft.AspNetCore.Builder。有了这个,如何让记录器在 MiddleWare 中工作的唯一方法是通过 ILoggerFactory 并创建记录器,但它只有一种方式工作

_logger = loggerFactory.CreateLogger( "ContextRequestLoggingMiddleware" )

一旦我将类放在不同的 NameSpace 下,其他方法也开始起作用

_logger = loggerFactory.CreateLogger<ContextRequestLoggingMiddleware>()

而且ILogger<ContextRequestLoggingMiddleware>现在也可以通过

所以下面的建筑类现在对我有用。有趣的是名称空间的更改如何使其工作。

namespace NPARetrieval.Middleware {
public class ContextRequestLoggingMiddleware {
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public ContextRequestLoggingMiddleware( RequestDelegate next, ILogger<ContextRequestLoggingMiddleware> logger ) {
        this._next = next;
        _logger = logger;
    }


    public async Task InvokeAsync (HttpContext context ) {
        _logger.LogInformation( "test from middleware" );
        await _next( context );    
    }
}

}

4

0 回答 0