在 ASP.NET MVC 中,如果 URL 段包含文字破折号并且其中一个参数约束允许破折号,我如何将 URLs 匹配到路由?

In ASP.NET MVC, how can I match URLs to a route if an URL segment contains literal dashes and one of the parameter constraints allows dashes?

给定这条路线:

{prefix}-{id}-{postfix}

有一个URL段和3个所谓的参数:prefixidpostfix。任何带有 3 个破折号的 URL 通常会匹配此路由(如果参数值匹配为这些参数定义的约束)。但是,一旦我为第三个参数定义了一个允许破折号的正则表达式约束,整个路由就不再匹配。

例如:

routes.MapRoute(
    url: "{prefix}-{id}-{postfix}", 
    constraints: new {
        prefix: "test",
        id: "42"
        postfix: "[a-z-]+"
    }
);

这将匹配到~/test-42-hello-world/

的请求

我的意思是 ASP.NET 路由引擎甚至不考虑此 URL 的路由。我知道这是因为我用自定义 IRouteConstraint 替换了其中一个约束并在其 Match() 方法中放置了一个断点,而我的断点从未被击中。

我想知道我想做的事情是否可行。

如果没有,我将非常感谢 link 一些文档(或来源),我可以查看这些文档以了解这不起作用的原因。

很简单,您的 URL 在这种情况下不匹配。 url patterns documentation 解释了它,但不幸的是不是很好。

In a URL pattern, you define placeholders by enclosing them in braces ( { and } ). You can define more than one placeholder in a segment, but they must be separated by a literal value. For example, {language}-{country}/{action} is a valid route pattern. However, {language}{country}/{action} is not a valid pattern, because there is no literal value or delimiter between the placeholders. Therefore, routing cannot determine where to separate the value for the language placeholder from the value for the country placeholder.

在确定文字值是什么时,同样的逻辑也适用。一旦将值用作文字,框架将无法区分文字和包含文字的占位符。

路由引擎首先查找的是已定义的 URL 模式。这发生在甚至考虑任何约束之前。

您的 URL 模式按顺序包含以下内容。

  1. 一个{prefix}占位符
  2. 文字 -(破折号)字符
  3. 一个{id}占位符
  4. 文字 -(破折号)字符
  5. 一个{postfix}占位符

你传入的虚拟路径test-42-hello-world每一个都比较

  1. 一个{prefix}占位符匹配test
  2. 文字 -(破折号)字符 匹配 -
  3. 一个 {id} 占位符 匹配 42
  4. 文字 -(破折号)字符 匹配 -
  5. 一个{postfix}占位符匹配hello

问题是现在虚拟路径末尾有额外的信息不匹配,即-world。这使得整个 URL 模式不匹配。