Search code examples
c#asp.net-mvcasp.net-mvc-routingurl-routing

How to remove Home from HomeController in Mvc


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

  • 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>