最近有人問我怎麼定製一個json序列化,使序列化的時候只寫出聲明的父類成員,而不要把實際子類的成員寫出來。固然,序列化用的是你們用的最多的json.net。git
簡單的說,這是個契約怎麼解析的問題,json.net選擇使用實際類型天然是有多方面的考量,畢竟申明類型能夠是抽象類或接口等。廢話不說了,直接上代碼(僅用於示例,要用於生產的話須要處理各類邊緣狀況)。github
類型關係json
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; } }
實例和序列化ide
var r = new RootObj { A = new B { X = "x", Y = "y" } }; Console.WriteLine(JsonConvert.SerializeObject(r));在什麼都不改的狀況下,輸出是:
{"A":{"Y":"y","X":"x"}}
{"A":{"X":"x"}}
寫本身的JsonConverter:.net
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(); } }
標記咱們的類型code
public class RootObj { [JsonConverter(typeof(JC<A>))] public A A { get; set; } }
Run! 而後就能夠發現結果和咱們期待的同樣了:)接口
源代碼傳輸門get