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
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.
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.
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:
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)
{
...
}
Manually generate this anchor:
<a href="@string.Format("{0}?{1}&page=5", Url.Action("action", "controller"), Request.QueryString)">abc</a>