Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 539
Daniel Avatar asked Jun 20 '11 20:06

Daniel


People also ask

What is the use of JavaScriptSerializer in C #?

The JavaScriptSerializer class is used internally by the asynchronous communication layer to serialize and deserialize the data that is passed between the browser and the Web server.

What is serializing and Deserializing JavaScript?

Summary. Serialization takes an in-memory data structure and converts it into a series of bytes that can be stored and transferred. Deserialization takes a series of bytes and converts it to an in-memory data structure that can be consumed programmatically.


2 Answers

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!

like image 55
Tomas Ojeda Avatar answered Sep 21 '22 10:09

Tomas Ojeda


I was able to solve with JavaScriptSerializer with Linq Select:

var dictionary = new Dictionary<int, string>();
var jsonOutput = new JavaScriptSerializer().Serialize(dictionary.Select(x => new { Id = x.Key, DisplayText = x.Value  }));
like image 25
Agiz Avatar answered Sep 19 '22 10:09

Agiz