Serializing dictionaries with JavaScriptSerializer

Daniel picture Daniel · Jun 20, 2011 · Viewed 20k times · Source

Apparently, IDictionary<string,object> is serialized as an array of KeyValuePair objects (e.g., [{Key:"foo", Value:"bar"}, ...]). Is is possible to serialize it as an object instead (e.g., {foo:"bar"})?

Answer

Tomas Ojeda picture Tomas Ojeda · Oct 31, 2012

Although I agree that JavaScriptSerializer is a crap and Json.Net is a better option, there is a way in which you can make JavaScriptSerializer serialize the way you want to. You will have to register a converter and override the Serialize method using something like this:

    public class KeyValuePairJsonConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        var instance = Activator.CreateInstance(type);

        foreach (var p in instance.GetType().GetPublicProperties())
        {
            instance.GetType().GetProperty(p.Name).SetValue(instance, dictionary[p.Name], null);
            dictionary.Remove(p.Name);
        }

        foreach (var item in dictionary)
            (instance).Add(item.Key, item.Value);

        return instance;
    }
    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var result = new Dictionary<string, object>();
        var dictionary = obj as IDictionary<string, object>;
        foreach (var item in dictionary)
            result.Add(item.Key, item.Value);
        return result;
    }
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new ReadOnlyCollection<Type>(new Type[] { typeof(your_type) });
        }
    }
}

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
javaScriptSerializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJsonConverter() });
jsonOfTest = javaScriptSerializer.Serialize(test);
// {"x":"xvalue","y":"\/Date(1314108923000)\/"}

Hope this helps!