使用Json.Net序列化NameValueCollection的自定义子类
我有以下类,我没有成功尝试序列化到Json.
class HL7 : NameValueCollection { public List<HL7> Children { get; set; } public HL7() { Children = new List<HL7>(); } } 我已经像这样创建了对象并向其添加了数据: HL7 hl7 = new HL7(); hl7.Add("a","123"); hl7.Add("b","456"); hl7.Children.Add(new HL7()); hl7.Children[0].Add("c","123"); hl7.Children[0].Add("d","456"); 我打电话的时候 JsonConvert.SerializeObject(hl7) 我收到 ["a","b"] 我期待以下: { "a": "123","b": "456","Children": [ { "c": "123","d": "456",} ] }
这里有一些事情:
> Json.NET无法在没有自定义转换器的情况下序列化 将所有这些放在一起,以下代码: [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) }); } } // Proxy dictionary to serialize & deserialize a NameValueCollection. We use a proxy dictionary rather than a real dictionary because NameValueCollection is an ordered collection but the generic dictionary class is unordered. public class NameValueCollectionDictionaryWrapper: IDictionary<string,string []> { readonly NameValueCollection collection; public NameValueCollectionDictionaryWrapper() : this(new NameValueCollection()) { } public NameValueCollectionDictionaryWrapper(NameValueCollection collection) { this.collection = collection; } // Method instead of a property to guarantee that nobody tries to serialize it. public NameValueCollection GetCollection() { return collection; } #region IDictionary<string,string[]> Members public void Add(string key,string[] value) { if (collection.GetValues(key) != null) throw new ArgumentException("Duplicate key " + key); foreach (var str in value) collection.Add(key,str); } public bool ContainsKey(string key) { return collection.GetValues(key) != null; } public ICollection<string> Keys { get { return collection.AllKeys; } } public bool Remove(string key) { bool found = ContainsKey(key); if (found) collection.Remove(key); return found; } public bool TryGetValue(string key,out string[] value) { value = collection.GetValues(key); return value != null; } public ICollection<string[]> Values { get { return Enumerable.Range(0,collection.Count).Select(i => collection.GetValues(i)).ToArray(); } } public string[] this[string key] { get { var value = collection.GetValues(key); if (value == null) throw new KeyNotFoundException(); return value; } set { Remove(key); Add(key,value); } } #endregion #region ICollection<KeyValuePair<string,string[]>> Members public void Add(KeyValuePair<string,string[]> item) { Add(item.Key,item.Value); } public void Clear() { collection.Clear(); } public bool Contains(KeyValuePair<string,string[]> item) { string [] value; if (!TryGetValue(item.Key,out value)) return false; return EqualityComparer<string[]>.Default.Equals(item.Value,value); // Consistent with Dictionary<TKey,TValue> } public void CopyTo(KeyValuePair<string,string[]>[] array,int arrayIndex) { foreach (var item in this) array[arrayIndex++] = item; } public int Count { get { return collection.Count; } } public bool IsReadOnly { get { return false; } } public bool Remove(KeyValuePair<string,string[]> item) { if (Contains(item)) return Remove(item.Key); return false; } #endregion #region IEnumerable<KeyValuePair<string,string[]>> Members public IEnumerator<KeyValuePair<string,string[]>> GetEnumerator() { foreach (string key in collection) { yield return new KeyValuePair<string,string[]>(key,collection.GetValues(key)); } } #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion } 使用以下测试用例: 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); 提供以下JSON: { "Values": { "a": [ "123" ],"b": [ "456" ],"Children": [ "Children" ] },"Children": [ { "Values": { "c": [ "123" ],"d": [ "456","789" ] },"Children": [] } ] } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |