大佬教程收集整理的这篇文章主要介绍了使用Json.Net序列化NameValueCollection的自定义子类,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
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无法在没有自定义转换器的情况下序列化NameValueCollection
,因为NameValueCollection实现了IEnumerable以迭代键,但没有实现IDictionary来迭代键和值.有关为何导致Json.NET出现问题的更全面解释,请参阅this answer.
>因为NameValueCollection实现了IEnumerable,Json.NET将您的类视为集合,因此将其序列化为JSON数组而不是具有命名属性的JSON对象.因此,您的孩子不是序列化的.同样,需要一个自定义转换器来解决这个问题.
>假设上述问题已解决,如果NameValueCollection的HL7子类碰巧有一个名为“Children”的键,则在序列化时会生成无效的JSON,即具有重复属性名称的对象.我建议移动名字和为了明确的序列化,将值转换为嵌套属性(命名为“Values”).
> NameValueCollection实际上可以为给定的键字符串提供多个字符串值,因此其条目值需要序列化为JSON数组而不是单个字符串.
[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": [] } ] }
以上是大佬教程为你收集整理的使用Json.Net序列化NameValueCollection的自定义子类全部内容,希望文章能够帮你解决使用Json.Net序列化NameValueCollection的自定义子类所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。