I have a HomeController and it has many Actions in it. I would like users to visit my actions without typing Home. Here is the Route below
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I would like users not to enter controller name, which is Home in this case. How can I do that? Or is it mandatory?
Solution 01 (attribute routing)
Add below line on the top of the other routes in RouteConfig
routes.MapMvcAttributeRoutes();
Then add an attribute route on top of each action as you want. (actions in the home controller in this case)
eg. Below code sample will remove "/Home" from http://site/Home/About and be available on http://site/About
[Route("About")]
public ActionResult About()
{
Solution 02 (using a Route constraint) [ Source ]
Add a new route mapping to RouteConfig as below. (Remember to add these specific routes before the default (generic) routes.
routes.MapRoute(
"Root",
"{action}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { isMethodInHomeController = new RootRouteConstraint<HomeController>() }
);
This will remove "Home" from all the actions (routes) of the Home controller RootRouteConstraint class
public class RootRouteConstraint<T> : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var rootMethodNames = typeof(T).GetMethods().Select(x => x.Name.ToLower());
return rootMethodNames.Contains(values["action"].ToString().ToLower());
}
}
Optional Info: This line (constraint) will make sure to apply this routing only for the HomeController
new { isMethodInHomeController = new RootRouteConstraint<HomeController>