【问题标题】:Core API Controller to catch all unknown routes用于捕获所有未知路由的核心 API 控制器
【发布时间】:2019-06-13 19:25:24
【问题描述】:

我有一个带有一堆现有控制器的 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/some/random/unknown/route 我正试图抓住这个并将其路由到 ../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");
    }
}

关于如何让它发挥作用的任何想法?

【问题讨论】:

  • 你试过中间件吗?您可以编写自己的自定义中间件
  • 如果我收集正确,这是针对 api 而不是整个应用程序?
  • @avin 正确,只有这个控制器。

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


【解决方案1】:

Catch all routes 使用 *** 语法指定。将[Route("{**catchall}")] 放在您想要成为所有操作的操作上。这将为所有以控制器路由属性中指定的前缀为前缀的路由创建一条捕获所有路由。

[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

如果你想设置一个站点范围的捕获所有路由,你可以使用绝对 url

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

}

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

【讨论】:

  • 所以不需要在启动配置中路由?
  • 该死,太简单了……我想得太多了!谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 2015-07-04
  • 2021-04-21
  • 1970-01-01
  • 2017-09-28
相关资源
最近更新 更多