【问题标题】:Catch all endpoint with regex使用正则表达式捕获所有端点
【发布时间】:2019-12-16 19:52:54
【问题描述】:

我希望捕获与特定格式(即regex 匹配)匹配的所有请求,以路由到我的 .NET Core 3.0 应用程序中的单个端点。

例如,我希望匹配格式为:

https://localhost:5001/test/status/1234567899999

其中/test/int ID 可以是任意程度的字符,因此是正则表达式。

The regex works fine, as seen here.

I've taken a look at this question 并写道:

        app.MapWhen(context => 
            Regex.IsMatch(context.Request.Path, @"/([a-zA-Z0-9_]+)/status/\d+"),
            test => test.UseMvc(routes => 
                                    routes.MapRoute(name: "Tweet", template: "{controller=Home}/{action=Test}")));

捕获每个请求,无论是否匹配正则表达式。

我也尝试过在 Route 属性中进行模式匹配:

    [HttpGet, Route(@"{path:regex(/([[a-zA-Z0-9_]]+)/status/d+)}")]
    public IActionResult Test([FromRoute] string path)
    {
        string s = string.Empty;

        return Ok(s);
    }

这没有捕获任何请求,但我可以在调试控制台中看到请求通过我的应用程序正常传输。他们只是从未达到定义的终点。

请注意,双 [[ ]] 用于按照 .NET Core 的指示在路由内部进行解析。

有没有更好的方法通过request.Path 匹配模式并将请求重新路由到控制器端点?

【问题讨论】:

  • 我自己没有使用过正则表达式路由规则,但阅读文档建议应该是Route(@"{path:regex(^[[a-zA-Z0-9]]+$)}/...")。由于每个路由参数都是针对每个约束独立测试的,因此正则表达式必须包含 ^$ 以比较整个字符串。
  • 你能用其他字符代替/吗?即@"/([a-zA-Z0-9_]+)/status/\d+") -> @"/([a-zA-Z0-9_]+)--status--\d+") 然后您可以在代码中手动将所有-- 转换为/

标签: c# asp.net-core .net-core


【解决方案1】:

您可以使用Custom Route Constraints

第 1 步:通过实现 IRouteConstraint 创建路由约束。

public class RegexConstraint : IRouteConstraint
{
    public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        return Regex.IsMatch(httpContext.Request.Path, "\\w+[-]{2}status[-]{2}\\d+");
    }
}

第 2 步:注册您的约束 Startup.cs -> ConfigureServices 类似方法

services.AddRouting(options => { options.ConstraintMap.Add("regexRouter", typeof(RegexConstraint)); });

第 3 步:使用您的自定义路由约束,如下所示

public class TestController : Controller
{
    [HttpGet("test/index/{path:regexRouter}")]
    public IActionResult Index([FromRoute] string path)
    {
        return Ok(path);
    }

    [HttpGet("test/get/{id:int}")]
    public IActionResult Get([FromRoute] int id)
    {
        return Ok(id);
    }
}

现在如果你运行你的应用程序并输入

1--> https://localhost:5001/test/index/longinitial--status--122 输出'longinitial--status--122'

2--> https://localhost:5001/test/get/123 输出123

要构建路径,您只需在 Index 操作中将 -- 替换为 /

path = path.Replace("--", "/");

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    相关资源
    最近更新 更多