解决方法 "捕获全部参数只能显示为路由模板的最后一段。



如果我有一个具有操作方法的控制器,该方法使用基于属性的路由并这样声明,则一切都很好:

    [HttpGet]
    [Route("/dev/info/{*somevalue}")]
    public IActionResult Get(string somevalue) {
        return View();
    }

我可以通过指定在/dev/info/hello-world/dev/info/new-world

中结束的URL来路由到上述操作方法

但是,我的业务需求是要拥有一个看起来像这样的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

相关内容

  • 没有找到相关文章

最新更新