Reputation: 6422
Having some trouble with some routes. I don't fully understand the MVC routing system so bear with me.
I've got two controllers, Products and Home (with more to come!).
I want to have the views within the Home controller accessible without having to type Home in the url. Essentially I want to turn www.example.com/home/about into www.example.com/about, however I still want to preserve the www.example.com/products.
Here's what I have so far.
routes.MapRoute( "Home", "{action}", new { controller = "Home" } );
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "home", action = "index", id = UrlParameter.Optional }
);
Now depending on which one is first I can get either one or the other to work, but not both.
Upvotes: 2
Views: 859
Reputation: 1835
Have you tried:
routes.MapRoute(
"Home_About",
"About",
new { controller = "Home", action = "About" } );
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "home", action = "index", id = UrlParameter.Optional }
);
Products should still be handled by the Default route, while the first one can handle your About route.
Upvotes: 1
Reputation: 2552
I think what you might be looking for is something that that the author of the code below has termed a Root Controller. I have used this myself on a couple sites, and it really makes for nice URLS, while not requiring you to create more controllers that you'd like to, or end up with duplicate URLs.
This route is in Global.asax:
// Root Controller Based on: ASP.NET MVC root url’s with generic routing Posted by William on Sep 19, 2009
// http://www.wduffy.co.uk/blog/aspnet-mvc-root-urls-with-generic-routing/
routes.MapRoute(
"Root",
"{action}/{id}",
new { controller = "Root", action = "Index", id = UrlParameter.Optional },
new { IsRootAction = new IsRootActionConstraint() } // Route Constraint
);
With this defined elsewhere:
public class IsRootActionConstraint : IRouteConstraint
{
private Dictionary<string, Type> _controllers;
public IsRootActionConstraint()
{
_controllers = Assembly
.GetCallingAssembly()
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(Controller)))
.ToDictionary(key => key.Name.Replace("Controller", ""));
}
#region IRouteConstraint Members
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
string action=values["action"] as string;
// Check for controller names
return !_controllers.Keys.Contains(action);
}
#endregion
}
The RootActionContraint alows you to still have other routes, and prevents the RootController actions from hiding any controllers.
You also need to create a controller called Root. This is not a complete implementation. Read the original article here
Upvotes: 1