How to combine CatchAll and EndsWith in an MVC route?

The following route will match any folder structure below BasePath:

http://BasePath/{*SomeFolders}/ 

How to create another route that will match any zip file under the same BasePath?

I tried this ...

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

... but these are errors with

A path segment that contains more than one section, such as a literal section or parameter, cannot contain the catch-all parameter. Parameter Name: routeUrl

How do I approach this?

* Update *

The initial requirements are actually erroneous. {ZipFile} will match the final section no matter what it contains. (File or Folder)

In fact, I believe that the route pattern I'm looking for should match:

 http://BasePath/{*SomeFolders}/{ZipFile}.zip 
+6
source share
3 answers

Catching everything in the url is exactly what you need

I wrote a Route class that allows you to do what you describe. It allows you to place the entire catch-all segment as the first in the route definition (or anywhere else actually). This will allow you to define your route as:

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

All of this is described in detail in my blog post , where you will find the code for this Route class.

Additional Information

Based on the added information, I would prefer to use the first route definition, which does not exclude the file extension from the route segment parameter, but rather adds a restriction for the last segment

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

Thus, the routing should be defined as indicated above in my answer, but the contrast for the ZipFile should be defined as indicated earlier. This will make my special route work out of the box, as it is now.

To also work with other route separators (for example, the dot in your example), the code needs to be significantly modified, but if you know how routing works well, you can change it that way.

But I would prefer that you keep it simple and add a restriction.

+4
source

There seem to be limitations.

  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"} _ ) 

or for those of you who prefer C # ...

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

(I think it is right)

The same route is registered twice, while the first option gives an additional restriction, which the RestOfPath parameter must end with ".zip"

I was given to understand that Custom Constraints are also possible using derivatives from IRouteConstraint.

+6
source

As the error says, your catchall should be the last parameter of your route.

To get the ZipFile part, you have to analyze it using the SomeFolders utility:

 public ActionResult MyAction(string SomeFolders) { // parse the ZipFile out from the SomeFolders argument } 

So, if you have / folder 1 / folder2 / folder3 / file.zip, you can do this:

 var zipFile = SomeFolders.SubString(SomeFolders.LastIndexOf("/") + 1); 
+1
source

Source: https://habr.com/ru/post/912977/


All Articles