Another possible solution is to create a custom route
public class ParamsEnabledRoute : RouteBase { private Route route; public ParamsEnabledRoute(string url) { route = new Route(url, new MvcRouteHandler()); } public override RouteData GetRouteData(HttpContextBase context) { var data = route.GetRouteData(context); if (data != null) { var paramName = (string)data.Values["paramname"] ?? "parameters"; var parameters = context.Request.QueryString.AllKeys.ToDictionary(key => key, key => context.Request.QueryString[key]); data.Values.Add(paramName, parameters); return data; } return null; } public override VirtualPathData GetVirtualPath(RequestContext context, RouteValueDictionary rvd) { return route.GetVirtualPath(context, rvd); } }
Using:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new ParamsEnabledRoute("ParamsEnabled/{controller}/{action}/{paramname}")); }
Controller:
public class HomeController : Controller { public ActionResult Test(Dictionary<string, string> parameters) { } }
URL:
http:
Route Attribute:
public class RouteDataValueAttribute : ActionMethodSelectorAttribute { private readonly RouteDataValueAttributeEnum type; public RouteDataValueAttribute(string valueName) : this(valueName, RouteDataValueAttributeEnum.Required) { } public RouteDataValueAttribute(string valueName, RouteDataValueAttributeEnum type) { this.type = type; ValueName = valueName; } public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { if (type == RouteDataValueAttributeEnum.Forbidden) { return controllerContext.RouteData.Values[ValueName] == null; } if (type == RouteDataValueAttributeEnum.Required) { return controllerContext.RouteData.Values[ValueName] != null; } return false; } public string ValueName { get; private set; } } public enum RouteDataValueAttributeEnum { Required, Forbidden }
source share