Asp.NET: MVC paths of unknown length

I am creating an MVC application in asp.NET for a web portal. I prepared a series of controllers and matched all the paths that are not related to it to the page controller that displays the corresponding page.

My default route works as follows:

routes.MapRoute( "Default", "{level1}/{level2}/{level3}", new { controller = "Page", action = "Index", level1 = "home", level2 = "", level3 = "" } ); 

But this is a fixed width, it will only take up to three levels. In addition, I would like to control the actions added to the path, for example, โ€œeditโ€ and โ€œdeleteโ€. Is it possible?

 company/about/who_we_are/staff -> Controller: Page, Action: Index, Parms: company/about/who_we_are/staff company/about/who_we_are/staff/edit -> Controller: Page, Action: Edit, Parms: company/about/who_we_are/staff company/edit -> Controller: Page, Action: Edit, Parms: company 

Or is there a better way to simulate this? All page paths are in the database, so they change dynamically.

+3
source share
3 answers

You can use the route with Wild Card:

 "{*data}" 

take a look at this SO: ASP.net MVC custom handler / route restriction


a simple solution:

(not verified, but ...)

Route:

 routes.Add(new Route ( "{*data}", new RouteValueDictionary(new {controller = "Page", action = "Index", data = ""}), new PageRouteHandler() ) ); 

The handler will look like this:

 public class PageRouteHandler : IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { return new PageHttpHandler(requestContext); } } class PageHttpHandler : MvcHandler { public PageHttpHandler(RequestContext requestContext) : base(requestContext) { } protected override void ProcessRequest(HttpContextBase httpContext) { IController controller = new PageController(); ((Controller)controller).ActionInvoker = new PageActionInvoker(); controller.Execute(RequestContext); } } class PageActionInvoker : ControllerActionInvoker { protected override ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) { string data = controllerContext.RouteData.GetRequiredString("data"); string[] tokens = data.Split('/'); int lenght = tokens.Length; if (lenght == 0) return new NotFoundResult(); if (tokens[tokens.Length - 1] == "edit") { parameters["action"] = "edit"; lenght--; } for (int i = 0; i < length; i++) parameters["level" + (i + 1).ToString()] = tokens[i]; return base.InvokeActionMethod(controllerContext, actionDescriptor, parameters); } } 
+5
source

A greedy segment anywhere in the url, maybe? Wow!

I wrote a GreedyRoute class that supports a catch all segment anywhere in the URL. It has been a long time since you need it, but it may be useful to others in the future.

It supports any of the following patterns:

  • {segment}/{segment}/{*greedy} - this is already supported by default Route class
  • {segment}/{*greedy}/{segment} - greedy in the middle
  • {*greedy}/{segment}/{segment} - greedy at the beginning

You can read all the details in your blog post and get the code.

+2
source

As far as I know, you can use regular expressions to express routes (see the lower code section here ). It should be possible to create a regular expression string that can accept an undetermined number of sub-sections ("forward-slashe and text / number-groups") . Then you can parse the URL string in the application and get the corresponding section.

However, I am not able to write this line of regular expressions on my own without spending hours, so maybe someone can help you. :-)

+1
source

All Articles