1

I am developing a asp.net mvc 4 application where I need a custom route which will handle multiple parameters like this:

routes.MapRoute(
   "Default",                                              
   "FilteredResults/Filter1-{1stParam}/Filter2-{2ndParam}/..../Filter-N{nthParam}",                           // URL with parameters
   new { controller = "Home", action = "Index", id = "" }   defaults
    );

I want to be able to pass only a subset of the parameters to the route(depending if some filters are selected or not)

For example if I have only the second Filter selected, I want to reference it this way:

<a href="/FilteredResults/Filter2-1000">

Is this possible to do this in a single route without creating a lot of routes for each combination of filters?

3
  • 1
    Why don't you just use query string params? /FilteredResults?filter2=1000&filter3=400 etc. That's what they are for. It seems you are trying to reinvent the wheel. Commented Feb 27, 2015 at 6:33
  • @rism That is exactly the point, instead of /FilteredResults?filter2=1000&filter3=400 I want to have /FilteredResults/filter2=1000/filter3=400 Commented Feb 27, 2015 at 6:43
  • Why? What does that give you but an url with / instead of &? Commented Feb 27, 2015 at 6:47

2 Answers 2

3

You can try with following example

On RouteConfig :

routes.MapRoute("Name", "tag/{*tags}", new { controller = ..., action = ... });

On Controller :

ActionResult MyAction(string tags) {
    foreach(string tag in tags.Split("/")) {
        ...
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I will accept this as an answer althought I found this solution on another stackoverflow post before. I thought that there would be a better solution, but in this case this seems to be the only option.
This is documented here on MSDN.
0

You could create a custom RouteBase implementation that could handle this detail.

public class FilteredRoute : RouteBase
{
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;
        var path = httpContext.Request.Path;
        // Path always starts with a "/", so ignore it.
        var segments = path.Substring(1).Split('/');

        if (segments.Any() && segments[0].Equals("FilteredResults", StringComparison.OrdinalIgnoreCase))
        {
            var result = new RouteData(this, new MvcRouteHandler());

            result.Values["controller"] = "Filter";
            result.Values["action"] = "ProcessFilters";

            // Add filters to route data (skip the first segment)
            var filters = segments.Skip(1).ToArray();

            foreach (var filter in filters)
            {
                string key = ParseRouteKey(filter);
                var value = ParseRouteValue(filter);

                result.Values[key] = value;
            }
        }

        // Make sure to return null if this route does not match
        return result;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        VirtualPathData result = null;

        // Process outgoing route here (to rebuild the URL from @Html.ActionLink)

        return result;
    }
}

Note that if you do it this way, it won't matter what order the filters are supplied in as long as the URL starts with /FilteredResults/.

Then you just add it to your route configuration like this.

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

    // Add the filtered route
    routes.Add("Filtered", new FilteredRoute());

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.