C# 在ASP.NET MVC中,如何使用Html.ActionLink生成重复名称(';?v=1&v=2&v=3';)查询字符串

C# 在ASP.NET MVC中,如何使用Html.ActionLink生成重复名称(';?v=1&v=2&v=3';)查询字符串,c#,asp.net-mvc,C#,Asp.net Mvc,这不是一个关于如何将一系列复选框正确绑定到模型属性的问题(一个常见问题)——我的网站可以从请求中完美地读取复选框值,无论是POST还是GET+查询字符串 这是关于如何使用Html.ActionLink生成一个链接,以在查询字符串中正确设置多个复选框值的格式 因此,我有以下模型: public class ModelType { public string[] V { get; set; } } 我将,比如,3个复选框绑定到视图中的模型,因为我有三个可能的值(以及,是的,所述值的组合)

这不是一个关于如何将一系列复选框正确绑定到模型属性的问题(一个常见问题)——我的网站可以从请求中完美地读取复选框值,无论是POST还是GET+查询字符串

这是关于如何使用
Html.ActionLink
生成一个链接,以在查询字符串中正确设置多个复选框值的格式

因此,我有以下模型:

public class ModelType
{
    public string[] V { get; set; }
}
我将,比如,3个复选框绑定到视图中的模型,因为我有三个可能的值(以及,是的,所述值的组合)

这是最终的Html

<INPUT id="chk1" value="1" type="checkbox" name="V">
<INPUT id="chk2" value="2" type="checkbox" name="V">
<INPUT id="chk3" value="3" type="checkbox" name="V">
版本2:将“V”成员直接初始化为数组:

<%= Html.ActionLink("Test link", null /* action name */,
    new { V = new string[] { "1", "2", "3" } }) %>
RouteValueDictionary也不允许我们这样做:

new { V="1", V="2", ... }
d["V"] = "1"; d["V"] = "2"; ...
我还尝试了预处理RouteValueDictionary的绝望措施,因此对于每个
IEnumerable
,我生成一个字符串,每个值用逗号分隔,然后写回该字符串-因此查询字符串的结果如下:
?V=1%2C2%2C3

但是,MVC当然不会自动将这样的字符串绑定到数组中(您只需要在数组中得到一个带有逗号的字符串);因此,每个将以这种方式绑定的属性都必须是自定义绑定的-对我来说,这似乎是一个太多的环,无法跨越

看来我被卡住了

我错过什么了吗?我是否需要编写ActionLink的特殊版本来满足我的需求


一如既往,我非常感谢您的帮助。

所以我去研究了一下,这是我的观点。我希望有人能想出一个更乐观的答案,但不知何故,我不这么认为

始终遵循
Html.ActionLink
扩展方法,它生成的核心URL由(cough)密封和(cough cough!)内部
System.Web.Mvc.parsedurote
System.Web.Routing
程序集中的方法
Bind
生成

在这个方法的最后(这是一个反射器列表)——它是如何生成查询字符串的:

if (unusedNewValues.Count > 0)
{
    bool flag5 = true;
    foreach (string str2 in unusedNewValues)
    {
        object obj5;
        if (acceptedValues.TryGetValue(str2, out obj5))
        {
            builder.Append(flag5 ? '?' : '&');
            flag5 = false;
            builder.Append(Uri.EscapeDataString(str2));
            builder.Append('=');
            builder.Append(Uri.EscapeDataString(
              Convert.ToString(obj5, CultureInfo.InvariantCulture)));
        }
    }
}
首先我应该提到,
unusedNewValues
是一个
HashSet
,不幸的是,这意味着它只能呈现一个名称/值

您不能用嵌入的
a=b&a=c(…)
字符串伪造数据字符串,因为字符串值是转义的-因此,除非替换路由框架,否则根本不可能在Mvc中生成此类查询字符串

因此,另一种方法是编写一个集合数据类型,它执行以下操作(这是一个脏的实现):

公共类StringCollection:列表
{
公共重写字符串ToString()
{
//使用管道字符作为分隔符-但这不起作用
//如果所携带的绳子自然包含“|”!
返回字符串.Join(“|”,this.ToArray());
}
}
然后为首先使用默认方法的类型实现自定义模型绑定器(源自
DefaultModelBinder
),然后检查生成的集合中是否只有一个包含“|”字符的字符串。如果是这样,它将对集合进行后期处理,用单个字符串中的扩展值替换其内容

这是可怕的——但这是我目前能想到的所有解决方案中最不令人讨厌的


刚才我不得不对所有使用字符串集合的现有模型类型进行大量更改,这些字符串集合可能绑定到查询字符串值…

最近也遇到了类似的问题。我最终放弃了HtmlHelper/RouteValueDictionary,只是从头开始构建了我的URL。比如:

<a href="/Controller/Action?<%: string.Join("&", set.Select(i => "v=" + i))%>">Link</a>

也许不能迎合每个人的口味,但对我来说很管用

public class StringCollection : List<string>
{
  public override string ToString()
  {
    //use the pipe character as a delimiter - but this doesn't work
    //if the strings being carried around ccould naturally contain '|'!
    return string.Join("|", this.ToArray());
  }
}
<a href="/Controller/Action?<%: string.Join("&", set.Select(i => "v=" + i))%>">Link</a>