热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c#在ASP.NETMVC中,如何使用Html.ActionLink生成重复名称(‘?v=1&v=2&v=3’)查询字符串

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

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

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

所以我有以下模型:

public class ModelType
{
public string[] V { get; set; }
}

我将三个复选框绑定到视图中的该模型,因为我有三个可能的值(是的,这些值的组合).

这是最终的HTML




如果在将表单作为GET提交到服务器时检查所有三个值,则生成的查询字符串当然为?V = 1& V = 2& V = 3.

模型绑定的工作很漂亮,并且一切都很顺利.

但是,假设我想产生一个指向相同动作的链接,传递一个匿名类型或RouteValueDictionary来产生相同的查询字符串.逻辑表明您将执行以下操作:

版本1:将ModelType实例作为视图上的模型:

<%= Html.ActionLink("Test link", null /* action name */, new { V = Model.V }) %>

版本2:直接将’V’成员初始化为数组:

<%= Html.ActionLink("Test link", null /* action name */,
new { V = new string[] { "1", "2", "3" } }) %>

[在这个问题上,我说的是RouteValueDictionary,因为在两种情况下,这两种匿名类型在链接生成发生之前都变成了匿名类型.]

在这两种情况下,生成的查询字符串如下:?V = System.String [].

现在,我知道这是因为链接生成器只是在数组上调用ToString().但是似乎无法传递MVC一个会导致其生成?V = 1& V = 2& V = 3的值.

由于两种语言都不允许我们这样做:

new { V="1", V="2", ... }

RouteValueDictionary也无法让我们执行以下操作:

d["V"] = "1"; d["V"] = "2"; ...

我还尝试了对RouteValueDictionary进行预处理的绝望措施,以便为每个IEnumerable生成一个字符串,每个值均用逗号分隔,然后将该字符串写回-这样查询字符串就结束了像这样:?V = 1,2,3.

但是,当然,MVC不会自动将这样的字符串绑定到数组(您只需在数组中得到一个字符串,其中包含逗号即可);因此,将以这种方式绑定的每个属性都必须进行自定义绑定-对我而言,这似乎有点麻烦了.

所以看来我被卡住了.

我想念什么吗?我需要编写要执行的特殊版本的ActionLink吗?

一如既往的任何帮助,我们将不胜感激.

解决方法:

所以我已经去研究了,这是我的观点.我希望有人能提出一个更乐观的答案,但我认为不可以.

完全遵循Html.ActionLink扩展方法,它产生的核心URL是由(咳嗽)密封和(咳嗽!)内部类System.Web.Mvc.ParsedRoute生成的,并且该方法绑定在System.Web中路由组装.

在此方法的最后(这是一个Reflector列表)-这是它生成查询字符串的方式:

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中生成此类查询字符串.

结果,一种替代方法是编写一个收集数据类型,该数据类型将执行以下操作(这是一个肮脏的实现):

public class StringCollection : List
{
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());
}
}

然后为首先使用默认方法的类型实现一个自定义模型绑定程序(派生自DefaultModelBinder),然后检查所得集合是否仅包含一个带有’|’的字符串.里面的字符.如果是这样,它将对集合进行后处理,将其内容替换为来自单个字符串的扩展值.

这很可怕-但我目前能想到的所有解决方案中最讨厌的就是.

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


推荐阅读
author-avatar
狠心狼fd
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有