ASP.NET 核心 API 中的常规路由

Conventional Routing in ASP.NET Core API

问题:

我正在使用 NET Core 3.1 创建一个 API 应用程序。 我想避免在每个 ApiControllers 和 Actions 上设置路由属性。我在 UseEndpoints 上尝试了很多组合来设置常规路线,但我失败了。

使用某些配置我无法使 Api 正常工作,使用其他配置我在启动期间遇到此异常:

InvalidOperationException: Action 'ApiIsWorking' does not have an attribute route. Action methods on controllers annotated with ApiControllerAttribute must be attribute routed.

如何将 startup.cs 设置为使用其 class 名称自动映射控制器并使用其方法名称设置操作?

谢谢!

一些代码:

startup.cs

...
services.AddControllers()
...

app.UseHttpsRedirection()
   .UseRouting()
   .UseAuthentication()
   .UseEndpoints(endpoints => ?? )
   .UseCoreHttpContext()
   .UseServerConfiguration();

controller.cs

[ApiController]
public class BaseAPI : ControllerBase 
{
        [HttpGet]
        public string ApiIsWorking()
        {
            return "API is working!";
        }
}

解法:

,错误是添加了ApiController属性。删除它后,命令 UseEndpoints 开始工作。

我的错误是添加了能够识别哪些 classes 应该通过 API 公开的属性。没有必要,因为 UseEndpoints 仅映射继承自 ControllerBase 的 classes。

警告:

1)

2) 我强调 关于 .NET Core 中 Swashbuckle 的传统路由问题

编辑:

我试着在我的机器上设置它。当我从控制器中删除 Route 属性时,出现以下错误:

InvalidOperationException: Action 'WebAPISample.Controllers.WeatherForecastController.Index (WebAPISample)' does not have an attribute route. Action methods on controllers annotated with ApiControllerAttribute must be attribute routed.

错误消息本身是说 API 控制器必须使用属性路由。

我知道这不能回答您的问题,但是对于 .NET Core 3 APIs,这似乎是不可能的。

来自文档:

The [ApiController] attribute makes attribute routing a requirement. For example:

[Route("api/[controller]")] 
[ApiController] 
public class ValuesController : ControllerBase

Actions are inaccessible via conventional routes defined by UseMvc or UseMvcWithDefaultRoute in Startup.Configure.

在 MSDN 上参考 this page

你试过这个吗?

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

要为您的控制器和操作设置常规路由,您需要从控制器和操作中删除 [ApiController] 属性和 [Route] 属性,并在 UseEndpoints 中设置路由。

documentations中已经提到了:

The [ApiController] attribute makes attribute routing a requirement.

Actions are inaccessible via conventional routes defined by UseEndpoints, UseMvc, or UseMvcWithDefaultRoute in Startup.Configure.

例子

这是我的启动工作设置:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    public IConfiguration Configuration { get; }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

和示例 API 控制器:

public class ValuesController : ControllerBase
{
    // values/getall
    [HttpGet]
    public IEnumerable<string> GetAll()
    {
        return new string[] { "value1", "value2" };
    }

    // values/getitem/1
    [HttpGet]
    public string GetItem(int id)
    {
        return "value";
    }
}

如果您要走这条使用 .net 核心的传统路由的道路,这是我的建议。 完成 API 实施后,您将向其添加一些文档。人们通常使用这个nuget包Swashbuckle.AspNetCore,它实现了后来的OpenAPI(Swagger)标准。但是当你使用常规路由并且你想用这个工具生成文档时,问题就来了。

if you are using conventional routing (as opposed to attribute routing), any controllers and the actions on those controllers that use conventional routing will not be represented in ApiExplorer, which means Swashbuckle won't be able to find those controllers and generate Swagger operations from them

有关详细信息,请参阅此 link:Swashbuckle 希望这会在将来为您的 api

文档节省很多麻烦