Serializing an array of objects in JSON

I have a type that is a wrapper over a dictionary - basically a key / value store. I would like to serialize an array of objects of this type in JSON. I am new to JSON and Json.NET (newtonsoft.json).

My type has a method called ToJson that serializes its dictionary in json as follows

public string ToJson() { return JsonConvert.SerializeObject(this.values); } 

And then I try to serialize an array of these objects

 var json = JsonConvert.SerializeObject(objectArray) 

Of course, this does not work, because every object in the array is serialized, and I don’t know how to direct the serialization process to my ToJson method for each object.

I can make it work the way I want if I pass in an array of Dictionary objects.

Perhaps I am missing the serialization attribute?

EDIT:

After reading the additional documentation, I tried a shorter way (before considering the JsonConverter approach) - using "JsonPropertyAttribute". Applying it to a private member of the dictionary almost did the job, except that I also got the member name serialized, which I don't want. Any way to just serialize a member value, not a member name, using JsonPropertyAttribute?

+8
json c #
source share
2 answers

To serialize your wrapper class so that its internal dictionary appears in JSON, as if the wrapper were not there, you need a custom JsonConverter . A JsonConverter gives you direct control over what is serialized and / or deserialized for a particular class.

Below is a converter that should work for your business. Since you did not provide any information about your wrapper class other than a field named values to store the dictionary, I used reflection to access it. If your class has public methods for managing the dictionary directly, you can change it to use these methods if you want. Here is the code:

 class DictionaryWrapperConverter : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(MyWrapper)); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { MyWrapper wrapper = (MyWrapper)value; FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance); JObject jo = JObject.FromObject(field.GetValue(wrapper)); jo.WriteTo(writer); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject jo = JObject.Load(reader); MyWrapper wrapper = new MyWrapper(); FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance); field.SetValue(wrapper, jo.ToObject(field.FieldType)); return wrapper; } } 

To associate your own converter with your wrapper class, you can add the [JsonConverter] attribute to the class definition:

 [JsonConverter(typeof(DictionaryWrapperConverter))] class MyWrapper : IEnumerable { Dictionary<string, string> values = new Dictionary<string, string>(); public void Add(string key, string value) { values.Add(key, value); } IEnumerator IEnumerable.GetEnumerator() { return values.GetEnumerator(); } } 

The following is a complete demonstration of the converter in action, the first serialization and deserialization of one instance of a wrapper class, and then the serialization and deserialization of a list of wrappers:

 class Program { static void Main(string[] args) { MyWrapper wrapper = new MyWrapper(); wrapper.Add("foo", "bar"); wrapper.Add("fizz", "bang"); // serialize single wrapper instance string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented); Console.WriteLine(json); Console.WriteLine(); // deserialize single wrapper instance wrapper = JsonConvert.DeserializeObject<MyWrapper>(json); foreach (KeyValuePair<string, string> kvp in wrapper) { Console.WriteLine(kvp.Key + "=" + kvp.Value); } Console.WriteLine(); Console.WriteLine("----------\n"); MyWrapper wrapper2 = new MyWrapper(); wrapper2.Add("a", "1"); wrapper2.Add("b", "2"); wrapper2.Add("c", "3"); List<MyWrapper> list = new List<MyWrapper> { wrapper, wrapper2 }; // serialize list of wrappers json = JsonConvert.SerializeObject(list, Formatting.Indented); Console.WriteLine(json); Console.WriteLine(); // deserialize list of wrappers list = JsonConvert.DeserializeObject<List<MyWrapper>>(json); foreach (MyWrapper w in list) { foreach (KeyValuePair<string, string> kvp in w) { Console.WriteLine(kvp.Key + "=" + kvp.Value); } Console.WriteLine(); } } } 

Output:

 { "foo": "bar", "fizz": "bang" } foo=bar fizz=bang ---------- [ { "foo": "bar", "fizz": "bang" }, { "a": "1", "b": "2", "c": "3" } ] foo=bar fizz=bang a=1 b=2 c=3 
+7
source share

Try using any type of object. This is the generic Serializer JSON code that I use

 public class JsonUtils { #region public static string JsonSerializer<T>(T t) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(); ser.WriteObject(ms, t); string jsonString = Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); return jsonString; } /// <summary> /// JSON Deserialization /// </summary> public static T JsonDeserialize<T>(string jsonString) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); T obj = (T)ser.ReadObject(ms); return obj; } #endregion } 
-one
source share

All Articles