Shaun Poore
Shaun Poore

Reputation: 642

Use MVC routing to override controller name when presented with specific action

I'm attempting to specify a route in MVC4 that ignores a controller name if presented with a specific action name. For example.

mysite.com/AnyControllerNameHere/SpecificAction - Would let me specify the controller and action to use while

mysite.com/AnyControllerNameHere/NotSpecificAction - Would take me the the AnyControllerNameHere Controller and NotSpecificAction method like the MVC default.

I've attempted to code something up but it doesn't seem to do what I want. Full route config is just the MVC defaults plus me attempting to do this so...

    public static void RegisterRoutes(RouteCollection routes)
    {
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

       routes.MapRoute(
            "SpecificAction",
            "{controller}/SpecificAction",
            new { controller = "Home", action = "SpecificAction" }
            );


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

Upvotes: 2

Views: 7941

Answers (3)

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93424

The easiest way to do this would be to use a Route constraint.

routes.MapRoute(
    "SpecificAction",
    "{anyController}/{specificAction}",
    new {controller="Home", action="SpecificAction"},
    new {specificAction = "SpecificAction" }
 );

The key here is that you don't using the default {controller} and {action} but rather something different (they could be anything), but use the route constraint to lock it to the SpecificAction action.

Wim's method works as well.

Upvotes: 1

Wim Coenen
Wim Coenen

Reputation: 66703

When you write this:

routes.MapRoute(
    "SpecificAction",
    "{controller}/SpecificAction",
    new { controller = "Home", action = "SpecificAction" });

you intend to override the controller. However, the third argument cannot be used to override parameters. It merely provides the defaults for any parameters that aren't already provided by the URL.

So what you need is a route template which doesn't set the controller parameter, so that the default takes effect:

routes.MapRoute(
    name: "SpecificAction",
    url: "{ignored}/SpecificAction",
    defaults: new { controller = "Home", action = "SpecificAction" });

Upvotes: 5

Ant P
Ant P

Reputation: 25221

I don't believe that this can be easily achieved with MVC's built-in routing. You could consider writing a custom route handler or, alternatively, do something like the following to have the default route do the job for you:

public class BaseController : Controller
{
    public ActionResult SpecificAction()
    {
        return RedirectToAction("SpecificAction", "Home");
    }
}

public class SomeController : BaseController
{
    /* ... */
}

public class HomeController : BaseController
{
    public override ActionResult SpecificAction()
    {
        /* Do whatever */
    }
}

Upvotes: 0

Related Questions