Reputation:
The following route Page/View/Id
would go to the View
Method in the Page Controller. I'd also like the following route:
/{page-title}
to go to the same method. That's so I could have URLs like the following:
http://www.mysite.com/This-Is-a-Page
How do I configure this, considering This-Is-a-Page
might be a controller also?
Upvotes: 2
Views: 323
Reputation: 57907
If both your "controller" routes and "page" routes (see below) use the same /something
, then you're going to have to implement the following rules:
At the top of your routes:
route. MapRoute(
"ControllerRoute"
"{controller}",
new { controller = "Home", action = "Index" }
new { controller = GetControllerNameRegex() }
);
route.MapRoute(
"PageRoute",
"{pageSlug}"
new { controller = "Page", action = "ShowPage" }
);
Since you can't really do the latter programmatically, but you can do the former programmatically, you can add a custom constraint to your controller routes, so that it will only hit if you happen to type the name of a controller:
private static string GetControllerNameRegex()
{
var controllerNamesRegex = new StringBuilder();
List<string> controllers = GetControllerNames();
controllers.ForEach(s =>
controllerNamesRegex.AppendFormat("{0}|", s));
return controllerNamesRegex.ToString().TrimEnd('|');
}
private static List<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(type =>
type.IsSubclassOf(typeof(T))).ToList();
}
public List<string> GetControllerNames()
{
List<string> controllerNames = new List<string>();
GetSubClasses<Controller>().ForEach(type => controllerNames.Add(type.Name));
return controllerNames;
}
NB: Best course would be to make sure not to have any pages named after your controller, and you could use the above code to enforce that at runtime.
Upvotes: 4
Reputation: 6706
You might be able to add a catch all, like so (place this after the default routes):
routes.MapRoute(
null,
"{*query}",
new { controller = "SomeController", action = "SomeAction" }
);
And the action signature would look like this:
public ActionResult(string query)
Upvotes: 0