5

我刚刚将我的 ASP.NET Core WebApi 项目从 .NET Core 2.2升级到3.1

我已经修复了所有编译时错误,升级了我的 Nuget 包,现在我可以运行该应用程序了。

但是,当我调用Build()myIHostBuilder时,出现以下异常:

InvalidOperationException:尝试激活“MyProject.Api.Middleware.ExceptionHandlerMiddleware”时,无法解析“Microsoft.AspNetCore.Http.RequestDelegate”类型的服务。

无效操作异常

它所指的中间件是相当标准的。

ExceptionHandlerMiddleware.cs

public class ExceptionHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ExceptionHandlerMiddleware> _logger;

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

    public async Task InvokeAsync(HttpContext httpContext)
    {
        // redacted
    }
}

我的应用程序初始化的其余部分是相当标准的,从 2.2 到 3.1(2.2 正在工作)我没有太大变化。

我确实从 更改services.AddMvc()services.AddControllers()

程序.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    private static IHostBuilder CreateHostBuilder(string[] args)
    {
        return Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(builder =>
            {
                builder.UseSerilog().UseStartup<Startup>();
            })
            .ConfigureLogging((context, logging) =>
            {
                logging
                .AddConfiguration(context.Configuration.GetSection("Logging"))
                .AddConsole()
                .AddDebug();
            });
    }
}

还值得一提的是,ConfigureServices()方法 inStartup.cs被调用并且运行良好,但Configure() 从未运行。该Build()方法总是在应用程序到达Configure().

我的 Startup 的Configure方法签名如下所示:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
4

3 回答 3

4

我今天遇到了同样的问题并解决如下:

在 .net core 2.2 中,我将中间件添加到应用程序构建器中,并将中间件添加到服务集合中。显然,不再需要将中间件添加到服务集合中,并且会导致您发布的异常。

就我而言,删除线

services.AddSingleton<MyMiddleware>();

解决了这个问题。

于 2019-12-24T20:47:30.147 回答
4

这个问题的解决方案包含两个主要元素:

  1. .NET Core 3.0 引入了关于服务提供者验证的更改。
  2. 我的代码注册了太多的类,导致验证失败。

我的问题的解决方案是在中引入以下代码Program.cs

private static IHostBuilder CreateHostBuilder(string[] args)
{
    return Host.CreateDefaultBuilder(args)
        .UseDefaultServiceProvider(opt =>
        {
            // this overrides the default service provider options
            // so that it doesn't validate the service collection (which raises exceptions)
        })
        [ ... ]
}

感谢其他将我的注意力引向我的Startup.cs.

完整解释

我使用Scrutor来扫描程序集和自动注册类。Scrutor 正在查找并注册我的中间件类,例如ExceptionHandlerMiddleware.

它在 .NET Core 2.2 和 3.1 中都是这样做的。那么为什么它只在 Core 3.1 中出现问题呢?

因为 .NET Core 3.0 引入了通用主机作为构建主机的新默认方式。

该代码现在包含ValidateOnBuild在开发环境下默认启用的部分。这导致我的 ServiceProvider 在构建时进行验证。它无法解决RequestDelegate,因为我没有注册。

.UseDefaultServiceProvider((context, options) =>
{
    var isDevelopment = context.HostingEnvironment.IsDevelopment();
    options.ValidateScopes = isDevelopment;
    options.ValidateOnBuild = isDevelopment;
});
于 2020-01-06T02:20:59.413 回答
2

正如@user1796440 所说,我可以使用services.AddSingleton<MyMiddleware>();.

要修复它,您需要注册中间件,如下所示:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...
    app.UseMiddleware<ExceptionHandlerMiddleware>();
    //...
}
于 2019-12-26T06:32:08.103 回答