Here are a few things going on:
Json.NET cannot serialize NameValueCollection without a custom converter, because NameValueCollection implements IEnumerable to enumerate keys, but does not implement IDictionary for IDictionary keys and values. See this answer for a more complete explanation of why this is causing problems for Json.NET.
Since NameValueCollection implements IEnumerable , Json.NET sees your class as a collection and therefore serializes it as a JSON array, not a JSON object with named properties. This way your Children not serialized. Again, this will require a special converter.
Assuming that the above problems are resolved, if your subclass of HL7 NameValueCollection has a key named "Children" you will generate invalid JSON when it is serialized, namely, an object with duplicate property names. I suggest moving names and values ββto a nested property (called, for example, "Values") for unambiguous serialization.
NameValueCollection can actually have multiple string values ββfor a given key string, so its record values ββshould be serialized as a JSON array, and not as a single string.
Putting it all together, the following code:
[JsonConverter(typeof(HL7Converter))] public class HL7 : NameValueCollection { public List<HL7> Children { get; set; } public HL7() { Children = new List<HL7>(); } } public class HL7Converter : JsonConverter { class HL7Proxy { public NameValueCollectionDictionaryWrapper Values { get; set; } public List<HL7> Children { get; set; } } public override bool CanConvert(Type objectType) { return objectType == typeof(HL7); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var proxy = serializer.Deserialize<HL7Proxy>(reader); if (proxy == null) return existingValue; var hl7 = existingValue as HL7; if (hl7 == null) hl7 = new HL7(); hl7.Add(proxy.Values.GetCollection()); if (proxy.Children != null) hl7.Children.AddRange(proxy.Children); return hl7; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { HL7 hl7 = (HL7)value; if (hl7 == null) return; serializer.Serialize(writer, new HL7Proxy { Children = hl7.Children, Values = new NameValueCollectionDictionaryWrapper(hl7) }); } }
Using the following test case:
HL7 hl7 = new HL7(); hl7.Add("a", "123"); hl7.Add("b", "456"); hl7.Add("Children", "Children"); hl7.Children.Add(new HL7()); hl7.Children[0].Add("c", "123"); hl7.Children[0].Add("d", "456"); hl7.Children[0].Add("d", "789"); var json = JsonConvert.SerializeObject(hl7, Formatting.Indented); Debug.WriteLine(json);
Gives the following JSON:
{ "Values": { "a": [ "123" ], "b": [ "456" ], "Children": [ "Children" ] }, "Children": [ { "Values": { "c": [ "123" ], "d": [ "456", "789" ] }, "Children": [] } ] }
dbc
source share