如果我有一个具有操作方法的控制器,该方法使用基于属性的路由并这样声明,则一切都很好:
[HttpGet]
[Route("/dev/info/{*somevalue}")]
public IActionResult Get(string somevalue) {
return View();
}
我可以通过指定在/dev/info/hello-world
或/dev/info/new-world
但是,我的业务需求是要拥有一个看起来像这样的URL:/dev/hello-world/info
或/dev/new-world/info
,并且有一组无尽的URL集需要将其路由到控制器上的相同操作方法。
我想在操作方法上设置基于属性的路由,如下所示:
[HttpGet]
[Route("/dev/{*somevalue}/info/")]
public IActionResult Get(string somevalue) {
return View();
}
但是,当我这样做时,我会在Web项目运行后立即遇到以下错误:
处理请求时发生了一个未经治疗的例外。 RouteCreationException:属性路由信息发生以下错误:
进行操作:'app.somecontroller.get(1 wwwsomeproject)' 错误:ALL参数只能显示为路由模板的最后一段。 参数名称:路由板 microsoft.aspnetcore.mvc.internal.attributeroute.getrouteinfos(ireadonlylist动作)
必须有某种方法可以解决此错误。知道一种方法吗?
可以通过使用正则表达式来实现此目标:
[HttpGet]
[Route(@"/dev/{somevalue:regex(^.*$)}/info/")]
public IActionResult Get(string somevalue)
{
return View();
}
关于使用正则表达式的路由约束,请参见文档中:路由约束参考
正则表达令牌解释:
token | 说明 |
---|---|
^ | 在线路开始时断言位置 |
。 | 匹配任何字符(线路终结者除外) |
* | 匹配以前的令牌零和无限时间,尽可能多次 |
$ | 断言在行末尾的位置 |
中间件是实现此目标的方法。
如果您需要API响应很容易实现。
if (app.Environment.IsDevelopment())
{
app.Use(async (context, next) =>
{
Console.WriteLine(context.Request.Path);
if (context.Request.Path.ToString().EndsWith("/info"))
{
// some logic
await context.Response.WriteAsync("Terminal Middleware.");
return;
}
await next(context);
});
}
如果您需要调用控制器,则可以简单地通过中间件编辑请求路径即可达到您的要求。
您可以在这里找到一个示例:https://stackoverflow.com/a/50010787/3120219