核心API控制器可捕获所有未知路由

时间:2019-06-13 19:25:24

标签: c# .net-core asp.net-web-api-routing .net-core-2.2

我有一个带有一堆现有控制器的Core 2.2 API。我现在想做的是添加一个新控制器,其功能类似于全能路由,但仅针对该控制器(并且不会干扰现有控制器的路由)

在我现有的控制器中,我将路由定义为控制器属性

[Route("api/[controller]")]
[ApiController]
public class SandboxController : ControllerBase
{
    [HttpGet("Hello")]
    public IEnumerable<string> Hello()
    {
        return new string[] { "Hello World", TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")).ToString()};
    }
}

对于这个新的“ catchall”控制器,我需要它能够捕获路由到它的任何Get,Post,Put,Delete 。例如,此控制器的路由为../ api / catchall 。如果有人要在../ api / catchall / 一些/随机/未知/路线中发帖,我想抓住它并将其路由到../ api / catchall / 发布

到目前为止,我完全没有成功。这就是我到目前为止所得到的:

在我的Startup.cs

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseAuthentication();

...

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Sandbox}/{action=Hello}/{id?}");

        routes.MapRoute(
            name: "catchall",
            template: "{controller}/{*.}", 
            defaults: new { controller = "catchall", action = "post" });
    });

和综合控制器:

[Route("api/[controller]")]
[ApiController]
public class CatchallController : ControllerBase
{
    [HttpPost("post", Order = int.MaxValue)]
    public IActionResult Post([FromBody] string value)
    {
        return Content("{ \"name\":\"John Doe\", \"age\":31, \"city\":\"New York\" }", "application/json");
    }
}

关于如何使它工作的任何想法吗?

1 个答案:

答案 0 :(得分:0)

Catch all routes***语法指定。将[Route("{**catchall}")]放在要成为全部捕获操作的操作上。这将捕获所有以Controller路由属性中指定的前缀为前缀的所有路由的所有路由。

[Route("api/[controller]")]
[ApiController]
public class CatchallController : ControllerBase
{
    [Route("{**catchAll}")]
    [HttpPost("post", Order = int.MaxValue)]
    public IActionResult Post([FromBody] string value, string catchAll)
    {
        return Content("{ \"name\":\"John Doe\", \"age\":31, \"city\":\"New York\" }", "application/json");
    }
}

在上面的示例中,这将捕获api/catchall/anything/following/it并将字符串catchAll设置为anything/following/it

如果您想设置站点范围内的所有路由,则可以使用绝对网址

[Route("/{**catchAll}")]
public IActionResult CatchAll(string catchAll)
{

}

这将捕获与任何其他指定路由都不匹配的任何路由。