6

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

http://BasePath/{*SomeFolders}/ 

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

我试过这个...

http://BasePath/{*SomeFolders}/{ZipFile}

...但它与

包含多个部分(例如文字部分或参数)的路径段不能包含包罗万象的参数。参数名称:routeUrl

我应该如何处理这个?

*更新*

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

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

http://BasePath/{*SomeFolders}/{ZipFile}.zip
4

3 回答 3

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 的衍生物。

于 2012-04-11T23:07:19.583 回答
4

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

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

"BasePath/{*SomeFolders}/{ZipFile}"

整个事情在我的博客文章中有详细的描述,你可以在其中找到这个Route类的代码。

附加信息

基于添加的信息,我仍然宁愿使用第一个不排除路由段参数中的文件扩展名的路由定义,而是为最后一个段添加约束

"[a-zA-Z0-9_]+\.zip"

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

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

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

于 2012-04-12T06:37:28.743 回答
1

正如错误所说,你的包罗万象必须是你路线中的最后一个参数。

要取出 ZipFile 部分,您必须从 SomeFolders 包中解析它:

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);
于 2012-04-11T22:56:35.473 回答