ASP.NET MVC Passing Lists to RouteData QueryString

3.5k views Asked by At

The recommended approach for passing lists of values as a QueryString is

www.site.com/search?value=1&value=2&value=3&value=4

ASP.NET handles this well:

string value = QueryString.Get("value"); // returns "1,2,3,4"

But I can't figure out a way of passing these values by into RouteData. The obvious approach would be to add

int[] value = {1,2,3,4};

into the RouteData and have super smart MVC sort things out for me. Unfortunately MVC is dump when it comes to passing arrays into RouteData, it basically calls .ToString() adding value=int[] to my QueryString.

I tried adding the values to RouteValueDictionary (but being a dictionary can't handle this:)

RouteValueDictionary dict = new RouteValueDictionary();
dict.Add("value","1");
dict.Add("value","2"); // Throws Exception (Keys must be unique)

I could try passing values like this:

www.site.com/search?value=1,2,3,4

but this is Encoded to the URL as

www.site.com/search?value=1%2C2%2C3%2C4

I'm not sure if this is a bad thing or not,but it sure looks bad.

So, how do you pass lists of values as RouteData in ASP.NET MVC. Is there any way I can add to MVC to make it handle an int[]? Or is the underlying Dictionary-based data structure a show-stopper for passing lists of values easily to ASP.NET MVC?

1

There are 1 answers

0
reach4thelasers On BEST ANSWER

I've come up with a solution to this myself by making a new class RouteDataList()

public class RouteDataList<T> : List<T>
{
    public RouteDataList(IEnumerable<T> enumerable) : base(enumerable) { }

    public RouteDataList() : base() { }

    public override string ToString()
    {            
        string output = "";
        for (int i = 0; i < this.Count; i++)
        {
            output += i < this.Count - 1 ? this[i] + "-" : this[i].ToString();
        }

        return output;
    }

    public static List<Int32> ParseInts(string input)
    {
        if (String.IsNullOrEmpty(input)) return null;

        List<Int32> parsedList = new List<int>();
        string[] split = input.Split('-');
        foreach (string s in split)
        {
            int value;
            if(Int32.TryParse(s, out value)) parsedList.Add(value);
        }
        return parsedList;
    }
}

Use as follows:

RouteDataList<Int32> valuelist = new RouteDataList<Int32>(){5,6,7,8};
RouteDataList<Int32> anothervaluelist = new RouteDataList<Int32>(){12,13,14,15};

Then Pass to any function that takes a RouteValueDictionary/Anonymous Type:

return RedirectToAction("View", "Browse", new {valuelist, anothervaluelist } );
// Produces http://www.site.com/browse/view?valuelist=5-6-7-8&anothervaluelist=12-13-14-15

// To Parse back to a list:
List<Int32> values = RouteDataList<Int32>.ParseInts(HttpContext.Current.Request.QueryString["valuelist"])