尝试构建一个中间件来记录每个请求的信息。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 );
}
}
}