如何在ASP.NET MVC 3中处理每个键的多个值?
我有以下问题:我在最重要的function中工作的系统之一是搜索页面。 在这个页面中,我有一些选项,如每页记录,开始日期,结束日期和有问题的一个:类型。 必须有可能选择多种类型(大多数时候,所有这些都将被选中)。 为了完成这项工作,我创建了以下内容:
@Html.ListBox("events", Model.Events, new { style = "width: 100%" })
它创建了一个列表框,我可以在其中选择多个选项,当表单被提交时,我的查询字符串将如下所示:
/ 10?周期= 9&事件= 1&事件= 3&recordsPerPage = 10
在那里可以看到创建了两个事件(这是我以前说过的类型)。 此页面的操作方法将List
作为其参数之一,表示两个events
值。 当我想在MVC Contrib中使用它时,问题就开始了。 他们的寻呼机工作得很好,但正如我所要求的那样,我创建了另一个寻呼机,它显示了用户所在之前和之后五个页面的链接。 为此,在我的代码的一部分中,我必须执行以下操作(这与MVC Contrib寻呼机非常相似,有效):
public RouteValueDictionary GetRoute(int page) { var routeValues = new RouteValueDictionary(); foreach (var key in Context.Request.QueryString.AllKeys.Where(key => key != null)) { routeValues[key] = Context.Request.QueryString[key]; } routeValues["page"] = page; return routeValues; }
然后:
@Html.ActionLink(page.ToString(), action, controller, GetRoute(page), null)
问题是它是一个Dictionary,它第二次设置routeValues["events"]
擦除前一个。
你们对如何使用它有什么想法吗?
非常好的问题。 不幸的是,使用Html.ActionLink
助手生成具有多个具有相同名称的查询字符串参数的URL并不容易。 所以我可以看到两种可能的解决方案
-
为
long[]
编写一个自定义模型绑定器,它能够解析逗号分隔值。 这样您就可以保留GetRoute
方法,该方法将生成以下url:period=9&events=1%2C3&recordsPerPage=10&page=5
。public class CommaSeparatedLongArrayModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (values != null && !string.IsNullOrEmpty(values.AttemptedValue)) { // TODO: A minimum of error handling would be nice here return values.AttemptedValue.Split(',').Select(x => long.Parse(x)).ToArray(); } return base.BindModel(controllerContext, bindingContext); } }
您将在
Application_Start
注册:ModelBinders.Binders.Add(typeof(long[]), new CommaSeparatedLongArrayModelBinder());
然后以下控制器操作将能够理解以前的URL:
public ActionResult Foo(long[] events, int page, int period, int recordsPerPage) { ... }
-
手动生成此锚点:
abc
尝试查看WinTellect的PowerCollections ,允许您创建MultiDictionary,仍然不能有重复的键,但每个键可以有多个值。
您应该编写以routeValue集合为目标的扩展方法,或者始终编写将Event参数转换为列表的自定义模型绑定器。 如果您将“事件”始终视为列表,则只需通常长度为1的列表即可缓解您遇到的大多数问题。
此时,您将只与列表界面进行交互。 然后,您可以编写自定义绑定器以允许您直接将其放入路径中,或者您可以将列表解压缩回查询字符串。 有一个基于这个名为Unbinder的软件项目,用于将对象解包为属性/值对,您可以在查询字符串或其他目的中轻松使用它们。