键 - 值对任意数量的ASP.NET路由 - 这可能吗? [英] ASP.NET route with arbitrary number of key-value pairs - is it possible?

查看:96
本文介绍了键 - 值对任意数量的ASP.NET路由 - 这可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想处理的URL是这样的:

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:

/{id}/{*parameters}

参数对象是作为一个单一的字符串来所有参与形成响应的动作传递。这并不工作,但我有这几个问题:

The parameters object is passed as a single string to all the actions that are involved in forming the response. This does work, but I have a few problems with it:


  1. 每个动作必须解决的字符串本身。我,当然,取得了转动字符串词典℃的扩展方法;字符串,字符串> ,但我preFER,如果调度机制,给我的方法词典<字符串,字符串> 直接 - 或更好,但实际对作为独立参数。

  2. 动作链接仍然可以添加使用传统的格式参数(?键1 =值)。我想我可以写专门的助手跟我想要的格式,但我preFER,如果有一种方法,使现有的重载按照上面的路由规则。

  1. Each action must resolve the string for itself. I've, of course, made an extension method that turns the string to a Dictionary<string, string>, but I'd prefer it if the dispatching mechanism gave my methods a Dictionary<string, string> directly - or, better yet, the actual pairs as separate arguments.
  2. Action links will still add parameters using the traditional format (?Key1=Value1). I guess I could write specialized helpers with my desired format, but I'd prefer it if there was a way to make the existing overloads follow the above routing rule.

有没有办法做上述?

推荐答案

您可以编写一个定制路线:

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",
        }) 
    }
)

或者如果你想要一个&LT;形式为GT;

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

这篇关于键 - 值对任意数量的ASP.NET路由 - 这可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆