I am building a MVC application in asp.NET for a web portal. I have prepared a series of controllers, and mapped all the paths that don\'t macth to this to a Page controller
You can use a wild-card route:
"{*data}"
take a look a this SO: ASP.net MVC custom route handler/constraint
(not tested but...)
The route:
routes.Add(new Route
(
"{*data}",
new RouteValueDictionary(new {controller = "Page", action = "Index", data = ""}),
new PageRouteHandler()
)
);
The handler would look like:
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);
}
}
I've written GreedyRoute
class that supports greedy (catch all) segment anywhere in the URL. It's been a while since you needed 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 with default Route
class{segment}/{*greedy}/{segment}
- greedy in the middle{*greedy}/{segment}/{segment}
- greedy at the beginningYou can read all the details on my blog post and get the code as well.
As far as i know, you can use regular expressions to express what the routes can look like (see the bottom code section here). With this, it should be possible to make a regex-string that can take an undetermined number of sub-sections ("forward-slashe and text/number-groups"). You can then parse the URL string in your application and retrieve the appropriate section.
I am, however, not capable of writing this regex-string by myself without spending hours, so someone else can probably help you there. :-)