48

I want to remove the controller name from my URL (for one specific controller). For example:

http://mydomain.com/MyController/MyAction

I would want this URL to be changed to:

http://mydomain.com/MyAction

How would I go about doing this in MVC? I am using MVC2 if that helps me in anyway.

James
  • 80,725
  • 18
  • 167
  • 237
  • Check the following link will help [How to remove the controller name from the url using rout in MVC](https://stackoverflow.com/questions/34650332/how-to-remove-the-controller-name-from-the-url-using-rout-in-mvc/34653793#34653793). – Kashif Saeed Jan 07 '16 at 11:27
  • SEE 2016 UPDATE AT BOTTOM – niico Oct 19 '16 at 16:03

6 Answers6

54

You should map new route in the global.asax (add it before the default one), for example:

routes.MapRoute("SpecificRoute", "{action}/{id}", new {controller = "MyController", action = "Index", id = UrlParameter.Optional});

// default route
routes.MapRoute("Default", "{controller}/{action}/{id}", new {controller = "Home", action = "Index", id = UrlParameter.Optional} );
rrejc
  • 2,682
  • 3
  • 26
  • 33
  • In MVC 4 I had to do this in RouteConfig.cs. Also remove the default route, its not enough to put the line before. – David Apr 25 '16 at 13:47
  • @David, the reason why you had to remove the default route is because your Home default index action matches `routes.MapRoute("Default", "{controller}/{action}/{id}", new {controller = "Home", action = "Index", id = UrlParameter.Optional} );`as well. It will force the MyController Index action to render instead of your home controller Index action because your home page call qualifies for that "Route". You can replace {action} with the actual name of the method without figure braces and it will ONLY call it when you are making a call to that specific action. – TarasBulba Sep 25 '16 at 03:05
  • See Attribute Routing answer below. – niico Nov 06 '16 at 20:27
  • @rrejc hey there, I just did as you said but, everything works perfectly for HomeController but other controllers such as AccountController are out of reach. Could you help? – Arya Dec 11 '20 at 20:24
34

To update this for 2016/17/18 - the best way to do this is to use Attribute Routing.

The problem with doing this in RouteConfig.cs is that the old route will also still work - so you'll have both

http://example.com/MyController/MyAction

AND

http://example.com/MyAction

Having multiple routes to the same page is bad for SEO - can cause path issues, and create zombie pages and errors throughout your app.

With attribute routing you avoid these problems and it's far easier to see what routes where. All you have to do is add this to RouteConfig.cs (probably at the top before other routes may match):

routes.MapMvcAttributeRoutes();

Then add the Route Attribute to each action with the route name, eg

[Route("MyAction")]
public ActionResult MyAction()
{
...
}
niico
  • 11,206
  • 23
  • 78
  • 161
  • i Have Created in same scenario and this working also my local project but not working in my production server. – Dip Girase Jun 21 '19 at 11:40
  • any need to route config.cs also define route or not? please suggest me. – Dip Girase Jun 21 '19 at 11:41
  • I suggest asking a new question about this, providing proof that you've tried to trouble shoot it yourself and include code examples... – niico Jun 21 '19 at 14:28
5

Here is the steps for remove controller name from HomeController

Step 1: Create the route constraint.

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());
    }
}

Step 2:
Add a new route mapping above your default mapping that uses the route constraint that we just created. The generic parameter should be the controller class you plan to use as your “Root” controller.

routes.MapRoute(
    "Root",
    "{action}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new { isMethodInHomeController = new RootRouteConstraint<HomeController>() }
);

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Now you should be able to access your home controller methods like so: example.com/about, example.com/contact

This will only affects HomeController. All other Controllers will have the default routing functionality.

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
Rahul
  • 2,431
  • 3
  • 35
  • 77
2

If you want it to apply to all urls/actions in the controller (https://example.com/action), you could just set the controller Route to empty above ApiController. If this controller going to be your starting controller, you'll also want to remove every launchUrl line in launchSettings.json.

[Route("")]
[ApiController]
Wes
  • 1,847
  • 1
  • 16
  • 30
0

You'll have to modify the default routes for MVC. There is a detailed explanation at ScottGu's blog: http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx

The method you should change is Application_Start. Something like the following might help:

RouteTable.Routes.Add(new Route(
  Url="MyAction"
  Defaults = { Controller = "MyController", action = "MyAction" },
  RouteHandler = typeof(MvcRouteHandler)
}

The ordering of the routes is significant. It will stop on the first match. Thus the default one should be the last.

sukru
  • 2,229
  • 14
  • 15
-2
routes.MapRoute("SpecificRoute", "MyController/{action}/{id}", 
         new {controller = "MyController", action = "Index", 
         id = UrlParameter.Optional});

// default route
routes.MapRoute("Default", "{controller}/{action}/{id}", 
         new {controller = "Home", action = "Index", 
         id = UrlParameter.Optional} );
David Watts
  • 2,249
  • 22
  • 33
Vijay S
  • 23
  • 3
  • 1
    `SpecificRoute` will only match if `MyController` is in the URL, the point of the question is to *exclude* the controller from the URL. See @rrejc's answer. – James Mar 12 '15 at 08:51