为什么在使用此 Regex 时会忽略 ASP.NET-MVC 路由的 UrlParameter.Optional?

Ben*_*son 5 regex asp.net-mvc routing url-routing asp.net-mvc-2

这是我今天早上在使用 ASP.NET MVC 的 URL 路由时遇到的一个问题的精简示例。

相当简单,我想要调用路由的 Action,无论是否提供了最后的参数。

这条路线工作正常,匹配/apple//apple/test/

路线.MapRoute(
    《工作路线》
    "苹果/{参数}",
    新的 { 
        控制器 = "苹果", 
        action = "动作", 
        参数 = UrlParameter.Optional
    },
    新 { 参数 = @"([a-z0-9\.-]+)" }
);

但是,第二条路线只会匹配/banana/test/等。当我尝试/banana/ 时,路由器正好经过它并返回全部 404 错误。

路线.MapRoute(
    "非工作路线",
    "香蕉/{参数}",
    新的 { 
        控制器 = "香蕉", 
        action = "动作", 
        参数 = UrlParameter.Optional
    },
    新 { 参数 = @"([a-z0-9]+)" }
);

唯一的区别是参数的正则表达式验证,但由于它是一个非常简单的正则表达式匹配,它们对于像/banana/这样的 URL 应该都可以正常工作,但第二条路由无法识别它。

我只是通过更改路线 #2 上的正则表达式以匹配路线 #1 上的正则表达式来回避我的问题,并接受 '.' 和“-”字符,我只是想知道是否有人知道为什么会发生这种情况。

编辑:

以下是我在示例中使用的控制器和操作。这里没什么好看的。

公共类 AppleController :控制器
{
    公共 ActionResult 动作(字符串参数)
    {
        如果(参数==空)
        {
            parameter = "没有指定参数。";
        }
        ViewData["参数"] = 参数;
        返回视图();
    }
}

公共类 BananaController :控制器
{
    公共 ActionResult 动作(字符串参数)
    {
        如果(参数==空)
        {
            parameter = "没有指定参数。";
        }
        ViewData["参数"] = 参数;
        返回视图();
    }
}

所以我的问题是/apple/会显示“没有指定参数。”,而/banana/给了我一个不想要的 404。


迄今为止..

在 Route 声明中使用parameter = URLParameter.Optional:Route #1 完美运行,Route #2 在没有参数的情况下不匹配。

在路由声明中使用参数 = "":当参数离开 URL 时,路由 #1 和路由 #2 都无法匹配。

在 Action 方法签名中声明参数 = "":由于 .NET 版本,不可能。

删除所有其他路由无效。

Max*_*oro 4

如果标记是可选的,那么您使用的任何正则表达式约束也必须反映这一点,例如(foo)?


我能够在 .NET 4 上使用 ASP.NET MVC 2 重现此问题。然后我升级到 ASP.NET MVC 3,一切都按预期工作。我上面提出的解决方案不适用于 ASP.NET MVC 2,但它适用于 ASP.NET MVC 3,因此我只能假设这是 v2 上的错误,现已在 v3 中修复。

您可以引用 v2,并在 web.config 上使用它来测试 v3:

<runtime>
   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
         <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
   </assemblyBinding>
</runtime>
Run Code Online (Sandbox Code Playgroud)