Reputation: 2049
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?
Upvotes: 1
Views: 1894
Reputation: 56859
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 }
);
}
Upvotes: 0
Reputation: 388
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("/")) {
...
}
}
Upvotes: 3