定制json序列化
Posted 我思故我在
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定制json序列化相关的知识,希望对你有一定的参考价值。
最近有人问我怎么定制一个json序列化,使序列化的时候只写出声明的父类成员,而不要把实际子类的成员写出来。当然,序列化用的是大家用的最多的json.net。
简单的说,这是个契约怎么解析的问题,json.net选择使用实际类型自然是有多方面的考量,毕竟申明类型可以是抽象类或接口等。废话不说了,直接上代码(仅用于示例,要用于生产的话需要处理各种边缘情况)。
类型关系
public class RootObj { public A A { get; set; } } public class A { public string X { get; set; } } public class B : A { public string Y { get; set; } }
实例和序列化
在什么都不改的情况下,输出是:var r = new RootObj { A = new B { X = "x", Y = "y" } }; Console.WriteLine(JsonConvert.SerializeObject(r));
{"A":{"Y":"y","X":"x"}}
而期望值是:
{"A":{"X":"x"}}
我们期望只输出A的成员。写自己的JsonConverter:
public class JC<T> : JsonConverter { public override bool CanConvert(Type objectType) => throw new NotImplementedException(); public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => throw new NotImplementedException(); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteStartObject(); var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(typeof(T)); foreach (var prop in contract.Properties) { writer.WritePropertyName(prop.PropertyName); serializer.Serialize(writer, prop.ValueProvider.GetValue(value)); } writer.WriteEndObject(); } }
标记我们的类型
public class RootObj { [JsonConverter(typeof(JC<A>))] public A A { get; set; } }
Run! 然后就可以发现结果和我们期待的一样了:)
以上是关于定制json序列化的主要内容,如果未能解决你的问题,请参考以下文章
json序列化时定制支持datetime类型,和到中文让他保留中文形式
Sublime Text自定制代码片段(Code Snippets)