DataContractJsonSerializer creates a list of hashes instead of a hash

I would expect a Dictionary object of the form:

var dict = new Dictionary<string,string>() { {"blah", "bob"}, {"blahagain", "bob"} }; 

for serialization in JSON as:

 { "blah": "bob", "blahagain": "bob" } 

NOT

 [ { "key": "blah", "value": "bob" }, { "key": "blahagain", "value": "bob"}] 

What is the reason why it seems like a monster of a typical attempt to serialize collections?

DataContractJsonSerializer uses the ISerializable interface to create this thing. It seems to me that someone took the XML output from ISerializable and looked for this thing from this.

Is there a way to override the default serialization used by .Net here? Can I just get the dictionary and override serialization methods?

Send messages about any reservations or offers that people may have.

+4
source share
1 answer

Well, I decided to bypass the serialization of DataContract for Dictionary objects.

I create two virtual methods in my root object.

 public virtual void prepareForSerialization(); public virtual void postDeserialize(); 

Then specify the properties of the DataMember class for each dictionary attribute of my classes. Lines become serialized, and the dictionary is no longer serialized directly.

 [DataMember] public string dictionaryString; public Dictionary<int, string> dict; 

Then, when my code calls serialization, it additionally first calls prepareForSerialization.

 public override void prepareForSerialization() { base.prepareForSerialization(); } public override void postDeSerialize() { base.postDeSerialize(); } 

Derived classes with dictionary members will then call my own serializer for the Dictionary.

Note. This is a simple serialization that suits my purposes. YMMV. Javascript commits the credit to another column. Forget which one.

 /// <summary> /// Extension methods needed to implement Javascript dates for C# /// </summary> public static class MyExtensions{ public static double JavascriptTicks(this DateTime dt) { DateTime d1 = new DateTime(1970, 1, 1); DateTime d2 = dt.ToUniversalTime(); TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks); return ts.TotalMilliseconds; } } /// <summary> /// Serialize a single value /// </summary> /// <param name="o">An object to serialize</param> /// <returns>A JSON string of the value</returns> if (o is string) { return string.Format("\"{0}\"", o); } else if (o is DateTime) { return string.Format("new Date({0})", ((DateTime)o).JavascriptTicks()); ; } else if(o.GetType().IsValueType) { return o.ToString(); } else { //Here you want a check of the form if is IMySerializer, then call your prepare before //using the .Net one. DataContractJsonSerializer json = new DataContractJsonSerializer(o.GetType()); using(MemoryStream ms = new MemoryStream()) using (StreamReader sr = new StreamReader(ms)) { json.WriteObject(ms, o); ms.Position = 0; return sr.ReadToEnd(); } } /// <summary> /// Serializes a List object into JSON /// </summary> /// <param name="list">The IList interface into the List</param> /// <returns>A JSON string of the list</returns> public string SerializeList(IList list) { string result = null; if (list != null) { IEnumerator it = list.GetEnumerator(); StringBuilder sb = new StringBuilder(); long len = list.Count; sb.Append("["); while (it.MoveNext()) { if (it.Current is IList) { sb.Append(SerializeList((IList)it.Current)); } else if (it.Current is IDictionary) { sb.Append(SerializeDictionary((IDictionary)it.Current)); } else { sb.Append(SerializeValue(it.Current)); } --len; if (len > 0) sb.Append(","); } sb.Append("]"); result = sb.ToString(); } return result; } /// <summary> /// Returns a stringified key of the object /// </summary> /// <param name="o">The key value</param> /// <returns></returns> public string SerializeKey(object o) { return string.Format("\"{0}\"", o); } /// <summary> /// Serializes a dictionary into JSON /// </summary> /// <param name="dict">The IDictionary interface into the Dictionary</param> /// <returns>A JSON string of the Dictionary</returns> public string SerializeDictionary(IDictionary dict) { string result = null; if (dict != null) { IDictionaryEnumerator it = dict.GetEnumerator(); StringBuilder sb = new StringBuilder(); long len = dict.Count; sb.Append("{"); while (it.MoveNext()) { sb.Append(SerializeKey(it.Key)); sb.Append(":"); if (it.Value is IList) { sb.Append(SerializeList((IList)it.Value)); } else if (it.Value is IDictionary) { sb.Append(SerializeDictionary((IDictionary)it.Value)); } else { sb.Append(SerializeValue(it.Value)); } --len; if (len > 0) sb.Append(","); } sb.Append("}"); result = sb.ToString(); } return result; } 
+1
source

Source: https://habr.com/ru/post/1305251/


All Articles