Core API 控制器捕获所有未知路由
Core API Controller to catch all unknown routes
我有一个 Core 2.2 API 和一堆现有的控制器。我现在想做的是添加一个新的控制器,它的行为类似于一个 catchall 路由,但仅适用于该控制器 (并且不会干扰现有控制器的路由).
在我现有的控制器中,我将路由定义为控制器属性
[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。如果有人在哪里做一个 post 到 ../api/catchall/some/random/unknown/route 我试图抓住这个并将它路由到 ../ api/catchall/post。
到目前为止,我完全没有成功。这是我到目前为止得到的:
在我的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" });
});
和 catchall 控制器:
[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");
}
}
关于如何让它工作的任何想法?
Catch all routes 使用 *
或 **
语法指定。将 [Route("{**catchall}")]
放在您希望成为捕获所有操作的操作上。这将为以 Controller 路由属性中指定的前缀为前缀的所有路由创建一个 catch all 路由。
[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
如果你想设置一个 site-wide catch all 路由你可以使用一个绝对 url
[Route("/{**catchAll}")]
public IActionResult CatchAll(string catchAll)
{
}
这将捕获与任何其他指定路由不匹配的任何路由。
我有一个 Core 2.2 API 和一堆现有的控制器。我现在想做的是添加一个新的控制器,它的行为类似于一个 catchall 路由,但仅适用于该控制器 (并且不会干扰现有控制器的路由).
在我现有的控制器中,我将路由定义为控制器属性
[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。如果有人在哪里做一个 post 到 ../api/catchall/some/random/unknown/route 我试图抓住这个并将它路由到 ../ api/catchall/post。
到目前为止,我完全没有成功。这是我到目前为止得到的:
在我的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" });
});
和 catchall 控制器:
[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");
}
}
关于如何让它工作的任何想法?
Catch all routes 使用 *
或 **
语法指定。将 [Route("{**catchall}")]
放在您希望成为捕获所有操作的操作上。这将为以 Controller 路由属性中指定的前缀为前缀的所有路由创建一个 catch all 路由。
[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
如果你想设置一个 site-wide catch all 路由你可以使用一个绝对 url
[Route("/{**catchAll}")]
public IActionResult CatchAll(string catchAll)
{
}
这将捕获与任何其他指定路由不匹配的任何路由。