.NET Core 2.1中间件输出List<string>遇实例创建异常求助
.NET Core 2.1中间件日志调用引发InvalidOperationException异常
问题代码与异常
LearningMiddleware类代码
namespace WebAspNetCore2_1 { public class LearningMiddleware { private readonly RequestDelegate _next; private readonly ILogger<LearningMiddleware> _logger_log; private readonly List<string> logger; public LearningMiddleware(RequestDelegate next,ILogger<LearningMiddleware> logger_log) { _next = next; _logger_log = logger_log; List<string> _logger = new List<string> { ("EUR/USD"), ("1.0500") }; logger = _logger; } public Task Invoke(HttpContext httpContext) { _logger_log.Log(Microsoft.Extensions .Logging.LogLevel.Information,"information of logger",logger[0]); return _next(httpContext); } } }
抛出的异常
InvalidOperationException: 无法创建类型为“Microsoft.Extensions.Logging.ILogger`1[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]”的实例。模型绑定的复杂类型不能是抽象类型或值类型,并且必须有无参数构造函数。或者,为“logger”参数提供非空默认值。
Startup配置代码
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // 此Lambda表达式确定对于给定请求是否需要用户同意非必要Cookie options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } // 运行时会调用此方法,用于配置HTTP请求管道 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // app.UseLearningMiddleware(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseMiddleware<LearningMiddleware>(); app.UseMvc(); }
问题原因
异常指向无法创建ILogger<string>实例,根源是直接调用ILogger.Log实例方法时参数传递错误:
Log实例方法的泛型重载要求传入TState、异常对象和格式化委托,你的调用方式导致编译器错误推断泛型参数为string,进而触发框架尝试解析不存在的ILogger<string>服务。- 直接调用
Log方法不符合日志API的常规用法,应该使用框架提供的扩展方法简化调用逻辑。
解决方案
修改Invoke方法中的日志调用代码,使用LogInformation扩展方法,并正确使用格式化占位符:
public Task Invoke(HttpContext httpContext) { // 使用LogInformation扩展方法,占位符{Message}会被logger[0]的值替换 _logger_log.LogInformation("information of logger: {Message}", logger[0]); return _next(httpContext); }
修改后,日志系统会正确处理参数,不会再尝试创建ILogger<string>实例,同时能正常输出logger[0]的内容("EUR/USD")。
内容的提问来源于stack exchange,提问作者Alfonso Castañeda
相关产品推荐
相关产品推荐

