以下路由将匹配BasePath下面的任何文件夹结构:
http://BasePath/{*SomeFolders}/
如何创建另一条匹配同一BasePath结构下任何zip文件的路由?
我试过了......
http://BasePath/{*SomeFolders}/{ZipFile}
...但
错误包含多个部分的路径段(例如文字部分或参数)不能包含catch-all参数。 参数名称:routeUrl
我该如何处理?
*的 更新 *
原始要求实际上是有缺陷的。 {ZipFile}将匹配最后一节,无论它包含什么。 (文件或文件夹)
实际上我相信我想要匹配的路线模式应该是:
http://BasePath/{*SomeFolders}/{ZipFile}.zip
答案 0 :(得分: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"} _
)
或者喜欢C#的人
routes.MapRoute(
"ViewFile", "BasePath/{*RestOfPath}",
new {controller = "File", action = "DownloadFile"},
new {RestOfPath = @".*\.zip"}
);
routes.MapRoute(
"ViewFolder", "BasePath/{*RestOfPath}",
new {controller = "Folder", action = "ViewFolder"}
);
(呃,我认为是对的)
相同的路由被注册两次,第一个变体被赋予了RestOfPath参数应以“.zip”结尾的附加约束
我理解使用IRouteConstraint的衍生物也可以使用自定义约束。
答案 1 :(得分:4)
我已经编写了这样的Route
课程,可以让您完全按照自己的描述进行操作。它允许您将catch-all段作为路径定义中的第一个段(或实际上的任何其他段)。它允许您将路线定义为:
"BasePath/{*SomeFolders}/{ZipFile}"
在my blog post上详细描述了整个内容,您可以在其中找到此Route
类的代码。
根据添加的信息,我仍然宁愿使用第一个路径定义,它不会将路径段参数中的文件扩展名排除在外,而是为最后一个段添加约束
"[a-zA-Z0-9_]+\.zip"
因此,路由仍应如上所述在我的答案中定义,但ZipFile
的约束应如先前所述定义。这将使我的特殊路线像现在一样开箱即用。
还要使其适用于其他路由分隔符(例如示例中的 dot )代码应该进行相当大的更改,但是如果您知道路由的工作方式非常好,则可以将其更改为方式。
但我建议你保持简单并添加约束。
答案 2 :(得分:1)
正如错误所说,你的捕获必须是你路线中的最后一个参数。
要获取ZipFile部分,您必须从SomeFolders catchall解析它:
public ActionResult MyAction(string SomeFolders)
{
// parse the ZipFile out from the SomeFolders argument
}
所以如果你有/folder1/folder2/folder3/file.zip,你可以这样做:
var zipFile = SomeFolders.SubString(SomeFolders.LastIndexOf("/") + 1);