Reputation: 457
Is it possible to map a route to a controller programmatically? In other words, I want to create a route without a controller, and based on the values of the rest of the parameters in the url map the correct controller to the request?
An example:
url: example.com/about-us
I want to look-up in our system which controller "about-us" is using and then set the controller for the request. It can't be a default controller since there will be many different pages like the one above, that uses different controllers.
Upvotes: 2
Views: 2179
Reputation: 709
I would suggest using custom IRouteHandler implementation. You can restrict route matching with constraints and then rewrite a controller to be instantiated within IRouteHandler implementation. E.g.
public class RewriteController : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// here some logic to determine controller name you would like
// to instantiate
var controllerName = ...;
requestContext.RouteData.Values["controller"] = controllerName;
return new HttpControllerHandler(requestContext.RouteData);
}
}
Then your route may be like the following:
routes.MapHttpRoute
(
name: Guid.NewGuid().ToString(),
routeTemplate: "{controller}/{action}",
defaults: new { action = "Index" },
constraints: new
{
controller = "about-us"
}
).RouteHandler = new RewriteController();
Upvotes: 1
Reputation: 10512
Why would you need this? Normal MVC way for handling such situations is to add different routes for different controllers, specifying values of parameters inside routes themselves or using RouteConstraint
s.
Another approach (if you really inist on doing routing logic yourself) might be creating a "Routing controller" with, say, a single action which processes all the queries. Inisde this action code you may check for parameter values and do return RedirectToAction(...)
to redirect request to any action on any controller you need.
UPDATE: Example code
In Global.asax.cs create the following default route:
routes.MapRoute(
"Default", // Route name
"{*pathInfo}", // URL with parameters
new { controller = "Route", action = "Index"} // Parameter defaults
);
Also add a controller class RouteController.cs with the following content:
// usings here...
namespace YourApp.Controllers
{
public class RouteController : Controller
{
public ActionResult Index(string pathInfo)
{
...
// programmatically parse pathInfo and determine
// controllerName, actionName and routeValues
// you want to use to reroute current request
...
return RedirectToAction(actionName, controllerName, routeValues);
}
}
}
Upvotes: 1