ASP.NET route with arbitrary number of key-value pairs - is it possible?

前端 未结 2 1573
孤城傲影
孤城傲影 2021-01-13 12:35

I\'d like to handle URLs like this:

/Id/Key1/Value1/Key2/Value2/Key3/Value3/

Right now, I have set up a rule like this:

/{i         


        
相关标签:
2条回答
  • 2021-01-13 12:50

    You could write a custom 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 could be registered like that:

    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 controller actions could take the following parameters:

    public ActionResult SomeAction(IDictionary<string, string> parameters)
    {
        ...
    }
    

    As far as generating links following this pattern is concerned, it's as simple as:

    @Html.RouteLink(
        "Go", 
        "my-route", 
        new {
            controller = "Foo",
            action = "Bar",
            parameters = new RouteValueDictionary(new { 
                key1 = "value1", 
                key2 = "value2",
            }) 
        }
    )
    

    or if you wanted a <form>:

    @using (Html.BeginRouteForm("my-route", new { controller = "Foo", action = "Bar", parameters = new RouteValueDictionary(new { key1 = "value1", key2 = "value2" }) }))
    {
        ...    
    }
    
    0 讨论(0)
  • 2021-01-13 13:04

    Write your own model binder for a specialized dictionary. If you will have one there will be no need for parsing the string in each action method.

    0 讨论(0)
提交回复
热议问题