如何在MVC路线中组合CatchAll和EndsWith?

Ror*_*ker 6 asp.net-mvc-3

以下路由将匹配BasePath下面的任何文件夹结构:

http://BasePath/{*SomeFolders}/ 
Run Code Online (Sandbox Code Playgroud)

如何创建另一个匹配同一BasePath结构下的任何zip文件的路由?

我试过这个......

http://BasePath/{*SomeFolders}/{ZipFile}
Run Code Online (Sandbox Code Playgroud)

......但它错了

包含多个节的路径段(例如文字节或参数)不能包含catch-all参数.参数名称:routeUrl

我该怎么做呢?

*更新*

原来的要求实际上是有缺陷的.{ZipFile}将匹配最后一节,无论它包含什么.(文件或文件夹)

实际上我相信我想要匹配的路线模式应该是:

http://BasePath/{*SomeFolders}/{ZipFile}.zip
Run Code Online (Sandbox Code Playgroud)

Ror*_*ker 6

这似乎是约束的答案.

    routes.MapRoute( _
        "ViewFile", "BasePath/{*RestOfPath}", _
        New With {.controller = "File", .action = "DownloadFile"}, _
        New With {.RestOfPath = ".*\.zip"}
    )
    routes.MapRoute( _
        "ViewFolder", "BasePath/{*RestOfPath}", _
        New With {.controller = "Folder", .action = "ViewFolder"} _
    )
Run Code Online (Sandbox Code Playgroud)

或者对于那些喜欢C#的人...

    routes.MapRoute( 
        "ViewFile", "BasePath/{*RestOfPath}", 
        new {controller = "File", action = "DownloadFile"}, 
        new {RestOfPath = @".*\.zip"}
    );
    routes.MapRoute( 
        "ViewFolder", "BasePath/{*RestOfPath}", 
        new {controller = "Folder", action = "ViewFolder"} 
    );
Run Code Online (Sandbox Code Playgroud)

(呃,我认为这是对的)

相同的路由被注册两次,第一个变化被赋予RestOfPath参数应以".zip"结尾的附加约束.

我了解使用IRouteConstraint的衍生物也可以实现自定义约束.


Rob*_*nik 4

捕获 URL 中的所有内容 - 正是您所需要的

我编写了这样的Route课程,可以让您完全按照您所描述的方式进行操作。它允许您将包罗万象的路段作为路线定义中的第一个路段(或实际上的其他任何地方)。它将允许您将路线定义为:

"BasePath/{*SomeFolders}/{ZipFile}"
Run Code Online (Sandbox Code Playgroud)

我的博客文章对整个事情进行了非常详细的描述,您可以在其中找到此类的代码Route

附加信息

根据添加的信息,我仍然宁愿使用第一个路由定义,该定义不会将文件扩展名排除在路由段参数之外,而是为最后一个段添加约束

"[a-zA-Z0-9_]+\.zip"
Run Code Online (Sandbox Code Playgroud)

因此,路由仍应按照我的答案中的上述方式进行定义,但 的约束ZipFile应按照之前编写的方式进行定义。这将使我的特殊路线像现在一样开箱即用。

为了使其适用于其他路由分隔符(例如示例中的),代码应该进行相当大的更改,但是如果您非常了解路由的工作原理,则可以更改它以这种方式工作。

但我宁愿建议你保持简单并添加一个约束。