仅使用' x'引起的神秘404路由错误字首?

时间:2014-09-16 20:36:44

标签: c# asp.net-mvc asp.net-mvc-5 url-routing asp.net-mvc-routing

我想让我的网址尽可能短,所以我正在测试没有分隔符的路由,如下所示:

routes.MapRoute(
   name: "Photo",
   url: "x{id}",
   defaults: new { controller = "Content", action = "Photo" }
);

出于某种原因,上面的路线不起作用,我收到404错误:

  

无法找到资源。

     

描述:HTTP 404.您正在寻找的资源(或其中一个   依赖项)可能已被删除,其名称已更改,或者是   暂时不可用。

但是当我为其他字母更改 x 前缀时,请说 g ,它可以正常工作。

没有相互冲突的路线。我在这里想念的是什么?

修改

我再次看到这个问题,我发现404可能只在id包含 x 时发生,即/xa1B2/xZ9y8等路线工作完美无缺,但x12xG失败了。有什么想法吗?

2 个答案:

答案 0 :(得分:7)

MSDN

  

您可以在分隔符之间定义多个占位符,但它们必须用常量值分隔。例如,{language} - {country} / {action}是有效的路由模式。但是,{language} {country} / {action}不是有效模式,因为占位符之间没有常量或分隔符。因此,路由无法确定将语言占位符的值与国家/地区占位符的值分开的位置。

如您所述,当您的ID以x开头时,会发生错误。这是因为它没有办法说出你的id值和你选择的常数之间的区别。

您可以使用一些选项来解决此问题:

  1. 在常量和占位符之间放置一个分隔符,该分隔符不会作为任何" id"的第一个字符出现。
  2. 选择一个不会作为任何" id"的第一个字符出现的常量的字符。
  3. 更改" id"所以它不能以x开头。
  4. 添加一个重复的路线,一个带有约束的路线绕过" id"包含x并以另一个角色开始第二条路线。
  5. 第四个选项看起来像这样:

    // Ids that don't contain x will use this route
    routes.MapRoute(
       name: "Photo_X",
       url: "x{id}",
       defaults: new { controller = "Content", action = "Photo" },
       constraints: new { id = @"(?i)[^x]" }
    );
    
    // Ids that contain x will use this route instead
    routes.MapRoute(
       name: "Photo_Y",
       url: "y{id}",
       defaults: new { controller = "Content", action = "Photo" }
    );
    

答案 1 :(得分:3)

在创建在常量值和参数之间没有分隔符的路径之前,我遇到了类似的问题。虽然我不能确切地解释为什么会发生这种情况,但我必须说明它给你带来的悲伤程度,为什么不花一个额外的角色来放一个' /&#39 ;或者' - '回到路线:

routes.MapRoute(
   name: "Photo",
   url: "x-{id}",
   defaults: new { controller = "Content", action = "Photo" }
);

我怀疑是否会为您解决问题,以及网址上的一个额外字符是什么?

编辑:

我有一种良好的感觉,我知道为什么会发生这种情况,但是我们无法找到任何证据来支持它。我怀疑,当您的网址包含x之类的其他x12xG时,路由引擎无法确定{id}12xG还是仅G因此它认为路线含糊不清并忽略它。由于您没有合适的后备路线,因此您将获得404。

根据我的评论,如果您可以使用路由约束来使用正则表达式限制{id}的允许值,那么您可以解决此问题。我认为你最好的选择是,如果{id}总是一个固定长度的字符串,那么你的约束可以强制执行这个,它可能会让你匹配。