ASP.NET 从 WebHostBuilder (Pre-.NET 3.0) 迁移到 IHostBuilder + ConfigureWebHostDefaults (Post-.NET 3.0) 导致 API 返回 404 错误

ASP.NET Migration from WebHostBuilder (Pre-.NET 3.0) to IHostBuilder + ConfigureWebHostDefaults (Post-.NET 3.0) causes API returning 404 error

我们有一个项目从 .NET Core 2.2 开始,最近迁移到 .NET 6。在这个项目中,我们使用了 WebHostBuilder,因为我们使用了 Rest API 和托管服务的组合,我们决定重新- 将我们的主机实现为 .NET Core 3 中引入的新通用主机。

但是在将我们的 WebHost 重新实现为通用主机 + WebHostDefaults 方法组合之后,我们所有的 API 调用开始出现 return 404 not found 错误消息,就好像控制器没有 found/mapped 正确以及我关于如何修复它的想法 运行。

我们的 HostBuilder 实现:

            var host = builder
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureWebHostDefaults((webBuilder) =>
            webBuilder.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
                      .UseWebHostConfiguration(ComponentName, commandLineArguments, out configuration)
                      .UseStartup(webHost => StartupClassFactory()))
            .Build();

启动时配置服务的实现Class:

        private void ConfigureServices(IServiceCollection services)
        {
            //Configure other non-API services

            services
                .AddMvc(options => options.EnableEndpointRouting = false)
                .AddNewtonsoftJson(options => JsonSettings.SetSettings(options.SerializerSettings));

        }

在启动时配置实现 Class:

        protected override void Configure(
            IApplicationBuilder app,
            ILoggerFactory loggerFactory,
            IServiceProvider serviceProvider,
            IHostApplicationLifetime applicationLifetime)
        {
            //Database Migration Stuff here

            app.UseMiddleware<InquiryMetricLogHandlerMiddleware>();
            app.UseMiddleware<ExceptionHandlerMiddleware>();
            app.UseMiddleware<SeedingCheckMiddleware>();

            if (QueryLocking)
            {
                QueryLockingMiddlewareApplicator(app);
            }

            app.UseMvc();
        }

控制器片段:

//Our Internal libraries
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace MyProject
{
    [ApiController]
    [Route(Routes.ApiRoute1 + "/{id:guid}/" + Routes.ApiRoute2)]
    public class CustomController : SqliteInquiryController<MyModel>
    {
        public TokensController(
            DI arg1,
            DI arg2,
            DI arg3)
            : base(arg1, arg2, arg3)
        {
            //Constructor stuff
        }
        
        [Route("/" + Routes.GetAllApiRoute), HttpGet, PaginationValidation]
        public override async Task<IActionResult> GetList()
        {
            //Build Database LINQ query
 
            return Ok(response);
        }
     }
}

在调试和尝试 /GetAllApiRoute API 调用时我发现,请求通过所有中间件并在 UseMvc 上停止,它只抛出 404 Not Found 响应所以注册 Controller 或将请求路由到 Controller 似乎有问题。

方法 ConfigurateServices 和 Configurate 与它们在 .NET 2.2 上的实现相同,并且一切正常。因此,我猜想从 .NET 2.2 到 .NET 6,WebHost 配置一定发生了一些变化,这使得这段代码无法正常工作,但我无法弄清楚是什么,而且我在网上也没有找到任何对我有帮助的东西。

这是我试过但没有帮助的方法:

任何帮助将不胜感激:)

对我来说,问题是我的 HostBuilder 与控制器在不同的程序集(库项目)中,因为它在多个不同的项目中使用。显然加载控制器的逻辑一定已经改变,它只在 HostBuilder 所在的程序集中寻找控制器。所以将 AddApplicationPart 添加到 ConfigureServices 解决了我的问题,现在一切正常。

解决方案代码:

services
       .AddControllers()
       .AddNewtonsoftJson(options => JsonSettings.SetSettings(options.SerializerSettings))
       .AddApplicationPart(Assembly.GetEntryAssembly()); //Adding this will look for Controllers in your Entry Point assembly where most likely your Controllers are