…meie igapäevast IT’d anna meile igapäev…


ASP.NET MVC: JSON and a generic dictionary

Filed under: ASP.NET MVC — Sander @ 13:39:29
Tags: ,

If you attempt to convert a generic dictionary to JSON – with keys that are not strings nor objects, you will get an error message similar to:

‘System.Collections.Generic.Dictionary`2[[System.Int64, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089]]’ is not supported for serialization/deserialization of a dictionary, keys must be strings or objects.

This is a runtime error, i.e. the application will compile just fine. This is an ASP.NET MVC limitation, probably existing because in JavaScript, array keys can only be strings (foo[“bar”] = “fubar”).

I wrote a simple extension method – it simply turns your dictionary into Dictionary<string, object> using the default .ToString() method – so if you are using a complex data structure as your keys, remember to override the .ToString() method.

public static Dictionary<string, object> ToJsonDictionary<TKey, TValue>(this Dictionary<TKey, TValue> input)
	var output = new Dictionary<string, object>(input.Count);
	foreach (KeyValuePair<TKey, TValue> pair in input)			
		output.Add(pair.Key.ToString(), pair.Value);
	return output;

Using the method is, of course, as easy as return Json(myDictionary.ToJsonDictionary());.

Generic Dictionary.AddRange() extension method.

In addition, another extension method.

For some reason, generic dictionary has gotten very little developer love from the creators of .NET, which is strange – dictionaries are one of the most widely used data structures together with the lists. Dictionaries cannot be serialized, they lack many useful methods – and one of the methods I’ve missed most is .AddRange(), ie. adding one dictionary to another.

So, another extension method:

public static void AddRange<TKey, TValue>(this Dictionary<TKey, TValue> input, Dictionary<TKey, TValue> addValues)
	foreach (KeyValuePair<TKey, TValue> pair in addValues)			
		input.Add(pair.Key, pair.Value);			

And that’s all. Simple, wasn’t it?


4 kommentaari »

  1. Do you have class to convert back from JSON Dictionary to type safe Dictionary (to use after deserialization) ?

    kommentaar kirjutas Michael Freidgeim — 2011-06-01 @ 05:08:13 | Vasta

    • No, I haven’t needed it. Also, System.Web.Script.Serialization.JavaScriptSerializer has methods Deserialize(), DeserializeObject() and ConvertToType() – these should work with Dictionary as well.

      kommentaar kirjutas Sander — 2011-06-02 @ 10:49:54 | Vasta

  2. Thank you for your advice. I’ve created JavaScriptSerializer extension DeserializeDictionary- see http://geekswithblogs.net/mnf/archive/2011/06/03/javascriptserializer-extension-deserializedictionarytkey-tvalue.aspx

    kommentaar kirjutas Michael Freidgeim — 2011-06-03 @ 15:39:56 | Vasta

RSS feed for comments on this post. TrackBack URI

Lisa kommentaar

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Muuda )

Twitter picture

You are commenting using your Twitter account. Log Out / Muuda )

Facebook photo

You are commenting using your Facebook account. Log Out / Muuda )

Google+ photo

You are commenting using your Google+ account. Log Out / Muuda )

Connecting to %s

Create a free website or blog at WordPress.com.