Asp.net-mvc – Asp.Net MVC – Best approach for “dynamic” routing

asp.net-mvcroutesrouting

I am trying to come up with an approach to create "dynamic" routing. What I mean, exactly, is that I want to be able to assign the controller and action of a route for each hit rather than having it mapped directly.

For example, a route may look like this "path/{object}" and when that path is hit, a lookup is performed providing the appropriate controller / action to call.

I've tried discovering the mechanisms for creating a custom route handler, but the documentation / discoverability is a bit shady at the moment (I know, its beta – I wouldn't expect any more). Although, I'm not sure if thats even the best approach and perhaps a controller factory or even a default controller/action that performs all of the mappings may be the best route (no pun intended) to go.

Any advice would be appreciated.

Best Answer

You can always use a catch all syntax ( I have no idea if the name is proper).

Route: routeTable.MapRoute( "Path", "{*path}", new { controller = "Pages", action = "Path" });

Controller action is defined as: public ActionResult Path(string path)

In the action for controller you will have a path, so just have to spilt it and analyse.

To call another controller you can use a RedirectToAction ( I think this is more proper way). With redirection you can set up a permanent redirectionfor it. Or use a something like that:

 internal class MVCTransferResult : RedirectResult
    {
        public MVCTransferResult(string url) : base(url) 
        {
        }
        public MVCTransferResult(object routeValues) 
                : base(GetRouteURL(routeValues))
        {
        }

        private static string GetRouteURL(object routeValues)
        {
            UrlHelper url = new UrlHelper(
                new RequestContext(
                        new HttpContextWrapper(HttpContext.Current),
                        new RouteData()),
                        RouteTable.Routes);
            return url.RouteUrl(routeValues);
        }

        public override void ExecuteResult(ControllerContext context)
        {
            var httpContext = HttpContext.Current;

            // ASP.NET MVC 3.0
            if (context.Controller.TempData != null &&
                context.Controller.TempData.Count() > 0)
            {
                throw new ApplicationException(
                     "TempData won't work with Server.TransferRequest!");
            }
            // change to false to pass query string parameters 
            // if you have already processed them
            httpContext.Server.TransferRequest(Url, true);

            // ASP.NET MVC 2.0
            //httpContext.RewritePath(Url, false);
            //IHttpHandler httpHandler = new MvcHttpHandler();
            //httpHandler.ProcessRequest(HttpContext.Current);
        }
    }

However this method require to run on IIS or a IIS Expres Casinni is not supporting a Server.Transfer method