Search code examples
c#jsonserializationjavascriptserializer

Serializing dictionaries with JavaScriptSerializer


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"})?


Solution

  • 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!