You can write your own route:
public class MyRoute : Route { public MyRoute() : base( "{controller}/{action}/id/{*parameters}", new MvcRouteHandler() ) { } public override RouteData GetRouteData(HttpContextBase httpContext) { var rd = base.GetRouteData(httpContext); if (rd == null) { return null; } string parameters = rd.GetRequiredString("parameters"); IDictionary<string, string> parsedParameters = YourExtensionMethodThatYouAlreadyWrote(parameters); rd.Values["parameters"] = parsedParameters; return rd; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { object parameters; if (values.TryGetValue("parameters", out parameters)) { var routeParameters = parameters as IDictionary<string, object>; if (routeParameters != null) { string result = string.Join( "/", routeParameters.Select(x => string.Concat(x.Key, "/", x.Value)) ); values["parameters"] = result; } } return base.GetVirtualPath(requestContext, values); } }
which can be registered as follows:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add("my-route", new MyRoute()); routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
and now your actions with the controller can take the following parameters:
public ActionResult SomeAction(IDictionary<string, string> parameters) { ... }
As for creating links following this pattern, it is as simple as:
@Html.RouteLink( "Go", "my-route", new { controller = "Foo", action = "Bar", parameters = new RouteValueDictionary(new { key1 = "value1", key2 = "value2", }) } )
or if you want <form> :
@using (Html.BeginRouteForm("my-route", new { controller = "Foo", action = "Bar", parameters = new RouteValueDictionary(new { key1 = "value1", key2 = "value2" }) })) { ... }