John
John

Reputation: 7049

Mvc's ASP.NET Routing integration: Controller/Action-to-Route-Resolution

Have a look at this route:

RouteTable.Routes.MapRoute(
   name: "FancyCustomerRoute",
   url: "fancy",
   defaults: new { controller = "SomeController", action = "Index", foo = "fancy" }
);

SomeController.Index is normally addressed as /Some/Index?foo=something, but for the fancy customer, it's simply /fancy with this route.

Through MVC's reverse route matching I expectedly get /Some/Index?foo=mundane for a call to Url.Action("Index", "Some", new { foo = "mundane" }) but just /fancy for Url.Action("Index", "Some", new { foo = "fancy" }).

So far, that's great.

However, I'm looking for a way to configure the route that the FancyCustomerRoute route is also not taken when the foo parameter is missing rather than different:

Url.Action("Index", "Some") currently also gives me \fancy, which I find undesirable.

What's the best way to address this problem?

I'm using MVC5.

Upvotes: 0

Views: 273

Answers (1)

Sam FarajpourGhamari
Sam FarajpourGhamari

Reputation: 14741

Simply write own Route class and use it as router, like this:

public class MyFancyRoute : Route
{
    public MyFancyRoute()
        : base("fancy", new MvcRouteHandler())
    {
        Defaults = new RouteValueDictionary { { "controller", "Some" }, 
        { "action", "Index" }, { "foo", "fancy" } };
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, 
        RouteValueDictionary values)
    {
        return values.ContainsKey("foo")
            ? base.GetVirtualPath(requestContext, values)
            : null;
    }
}

And in the RouteConfig write this instead of yours:

RouteTable.Routes.Add(new MyFancyRoute());

Upvotes: 1

Related Questions