How to deal with more than one value per key in ASP.NET MVC 3?

后端 未结 3 805
情话喂你
情话喂你 2020-12-29 09:21

I have the following problem: one of the system I\'m working in most important features is a search page. In this page I have some options, like records per page, starting d

相关标签:
3条回答
  • 2020-12-29 09:29

    Try looking at WinTellect's PowerCollections, allows you to create a MultiDictionary, still can't have duplicate keys, but you can have multiple values per key.

    0 讨论(0)
  • 2020-12-29 09:31

    You should write either extension methods that target the routeValue collection or a custom model binder that transforms your Event parameter into a list always. If you view Event always being a list, just a commonly length 1 list will alleviate most of the problems you face.

    At this point you will just interact with a list interface. You could then write a custom binder to allow you to directly place that into the route correctly or you could unpack the list back into the query string. There's a software project based on this called Unbinder for unpacking objects into property/value pairs that you can easily use in query strings or other purposes.

    0 讨论(0)
  • 2020-12-29 09:52

    Very good question. Unfortunately it is not easy to generate an url which has multiple query string parameters with the same name using the Html.ActionLink helper. So I can see two possible solutions:

    1. Write a custom model binder for long[] that is capable of parsing a comma separated values. This way you can keep your GetRoute method which will generate the following 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);
          }
      }
      

      which you will register in Application_Start:

      ModelBinders.Binders.Add(typeof(long[]), new CommaSeparatedLongArrayModelBinder());
      

      and then the following controller action will be able to understand the previous URL:

      public ActionResult Foo(long[] events, int page, int period, int recordsPerPage)
      {
          ...
      }
      
    2. Manually generate this anchor:

      <a href="@string.Format("{0}?{1}&page=5", Url.Action("action", "controller"), Request.QueryString)">abc</a>
      
    0 讨论(0)
提交回复
热议问题