简体   繁体   English

ASP.NET Core API 中的常规路由

[英]Conventional Routing in ASP.NET Core API

Problem:问题:

I'm creating an API Application with NET Core 3.1.我正在使用 NET Core 3.1 创建 API 应用程序。 I'd like to avoid to set route attribute over every ApiControllers and Actions.我想避免在每个ApiControllers和 Actions 上设置路由属性。 I tryed a lot of combinations over UseEndpoints to set a conventional route, but i'm failing.我在UseEndpoints了很多组合来设置常规路线,但我失败了。

With some configuration I can't get the Api working, with some others I get this exception during startup:对于某些配置,我无法使 Api 正常工作,而在其他一些配置中,我在启动过程中遇到此异常:

InvalidOperationException: Action 'ApiIsWorking' does not have an attribute route. InvalidOperationException:操作“ApiIsWorking”没有属性路由。 Action methods on controllers annotated with ApiControllerAttribute must be attribute routed.使用 ApiControllerAttribute 注释的控制器上的操作方法必须进行属性路由。

How can i set the startup.cs to auto map controllers with their class name and actions with their method name?我如何将startup.cs设置为使用类名和方法名自动映射控制器?

Thank you!谢谢!

Some code:一些代码:

startup.cs启动文件

...
services.AddControllers()
...

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

controller.cs控制器.cs

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

Solution:解决方案:

As Reza Aghaei says in the solution , the error was to add the ApiController attribute.正如 Reza Aghaei 在解决方案中所说,错误是添加了 ApiController 属性。 After I removed it, the command UseEndpoints start to work.删除它后,命令 UseEndpoints 开始工作。

My mistake was to add the attribute to be able to recognize which classes should be exposed via API.我的错误是添加属性以便能够识别应通过 API 公开哪些类。 It wasn't necessary because UseEndpoints maps only the classes that inherit from ControllerBase.这是没有必要的,因为 UseEndpoints 只映射从 ControllerBase 继承的类。

Warning:警告:

1) Conventional Routing require [FromBody] attribute in actions params. 1)常规路由需要动作参数中的[FromBody]属性。

2) I highlight Zinov's response about conventional routing problems with Swashbuckle in .NET Core 2) 我强调了 Zinov 对 .NET Core 中 Swashbuckle 的常规路由问题的回应

To have conventional routing for your controllers and action, you need to remove [ApiController] attribute and [Route] attribute from your controller and actions and setup route in UseEndpoints .要为您的控制器和操作进行常规路由,您需要从控制器和操作中删除[ApiController]属性和[Route]属性,并在UseEndpoints设置路由。

It's already mentioned in the documentations :它已经在文档中提到:

The [ApiController] attribute makes attribute routing a requirement. [ApiController]属性使属性路由成为一项要求。

Actions are inaccessible via conventional routes defined by UseEndpoints , UseMvc , or UseMvcWithDefaultRoute in Startup.Configure .操作经由不可访问常规途径由定义UseEndpointsUseMvc ,或UseMvcWithDefaultRouteStartup.Configure

Example例子

This is the working setup that I have for Startup:这是我用于启动的工作设置:

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?}");
        });
    }
}

And a sample API controller:和一个示例 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";
    }
}

EDIT:编辑:

I tried to set it up on my machine.我试图在我的机器上设置它。 When I removed the Route attribute from controller I got below error:当我从控制器中删除 Route 属性时,出现以下错误:

InvalidOperationException: Action 'WebAPISample.Controllers.WeatherForecastController.Index (WebAPISample)' does not have an attribute route. InvalidOperationException: Action 'WebAPISample.Controllers.WeatherForecastController.Index (WebAPISample)' 没有属性路由。 Action methods on controllers annotated with ApiControllerAttribute must be attribute routed .使用 ApiControllerAttribute 注释的控制器上的操作方法必须是属性 routed

The error message itself is saying that the API controllers must use attribute routing.错误消息本身是说 API 控制器必须使用属性路由。

I know this does not answer your question, but with .NET Core 3 APIs, this does not seem to be possible.我知道这不能回答您的问题,但是对于 .NET Core 3 API,这似乎是不可能的。

From Documentation:从文档:

The [ApiController] attribute makes attribute routing a requirement. [ApiController]属性使属性路由成为一项要求。 For example:例如:

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

Actions are inaccessible via conventional routes defined by UseMvc or UseMvcWithDefaultRoute in Startup.Configure .操作无法通过由Startup.Configure UseMvcUseMvcWithDefaultRoute定义的常规路由访问。

Refer this page on MSDN.请参阅 MSDN 上的此页面

你试过这个吗?

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

Here is my advice if you are going down this road of using conventional routing with .net core.如果您要沿着使用 .net core 的传统路由的道路走下去,这是我的建议。 After you finish your API implementation you are going to add some documentation to it.完成 API 实现后,您将向其中添加一些文档。 People normally use this nuget package Swashbuckle.AspNetCore, which implements the later standard of OpenAPI(Swagger).人们通常使用这个nuget包Swashbuckle.AspNetCore,它实现了后来的OpenAPI(Swagger)标准。 But here is the problem when you use conventional routing and you want to generate the documentation with this tool.但是当您使用传统路由并且想要使用此工具生成文档时,问题就出现了。

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如果您使用的是常规路由(而不是属性路由),则任何控制器以及使用常规路由的那些控制器上的操作都不会在 ApiExplorer 中表示,这意味着 Swashbuckle 将无法找到这些控制器并从中生成 Swagger 操作他们

For more information refer to this link : Swashbuckle Hope this saves you a lot of headaches in the future with the documentation for your api有关更多信息,请参阅此链接: Swashbuckle希望这可以为您的 api 文档在未来节省很多麻烦

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM