ASP.NET Core API中的常规路由

时间:2020-02-13 10:23:56

标签: c# asp.net-core asp.net-core-webapi asp.net-apicontroller asp.net-core-3.1

问题:

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

在某些配置下,我无法使Api工作,而在另一些配置下,我在启动期间遇到了此异常:

InvalidOperationException:操作'ApiIsWorking'没有 属性路由。用注释的控制器上的操作方法 ApiControllerAttribute必须进行属性路由。

如何设置startup.cs以使用其类名自动映射控制器,并使用其方法名来设置动作?

谢谢!

某些代码:

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!";
        }
}

解决方案:

As Reza Aghaei says in the solution,错误是添加ApiController属性。删除它之后,命令UseEndpoints开始起作用。

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

警告:

1)Conventional Routing require [FromBody] attribute in actions params.

2)我重点介绍{.3}关于.NET Core中Swashbuckle的常规路由问题

4 个答案:

答案 0 :(得分:7)

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

documentations中已经提到:

[ApiController]属性使属性路由成为必需。

通过UseEndpoints中的Startup.Configureconventional routesUseMvc定义的UseMvcWithDefaultRoute无法访问操作。

示例

这是我为“启动”准备的工作设置:

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

答案 1 :(得分:3)

编辑:

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

InvalidOperationException:操作 'WebAPISample.Controllers.WeatherForecastController.Index (WebAPISample)'没有属性路由。 操作方法 带有ApiControllerAttribute注释的控制器必须是attribute 已路由

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

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

摘自文档:

[ApiController]属性使属性路由成为必需。 例如:

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

通过UseMvcUseMvcWithDefaultRoute中的Startup.Configure

在MSDN上引用this page

答案 2 :(得分:2)

您尝试过吗?

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

答案 3 :(得分:2)

如果您正沿着将常规路由与.net内核结合使用的方式提出建议,请联系我。 完成API实施后,您将向其中添加一些文档。人们通常使用此nuget包Swashbuckle.AspNetCore,它实现了OpenAPI(Swagger)的更高标准。但是,当您使用常规路由并且要使用此工具生成文档时,就会出现问题。

如果您使用常规路由(而不是属性路由),则任何控制器以及使用常规路由的那些控制器上的操作都不会在ApiExplorer中表示,这意味着Swashbuckle将无法找到那些控制器并生成招摇动摇

有关更多信息,请参见以下链接:Swashbuckle 希望这会为您将来使用api文档省去许多麻烦