使用TypeNameHandling.Auto在JSON.NET中反序列化多型物件很簡單,但是如果您需要移除"$type"欄位怎麼辦?
方法一:將"$type"重新命名為自訂名稱
不幸的是,JSON.NET的內建選項無法重新命名"$type"。
方法二:在基底類別中加入子類型資訊
與其使用容器類別來保存子類型訊息,不如在基底類別(SubTypeClassBase)中新增一個名為「Type」的屬性:
<code class="language-csharp">[JsonConverter(typeof(SubTypeClassConverter))] public class SubTypeClassBase { [JsonConverter(typeof(StringEnumConverter))] public SubType Type { get { return typeToSubType[GetType()]; } } }</code>
這確保了在序列化SubTypeClassBase類型的物件時,始終包含子類型資訊。
自訂反序列化
為了正確反序列化JSON,建立一個自訂JsonConverter(SubTypeClassConverter),它讀取「Type」屬性,識別實際類型,並相應地進行反序列化:
<code class="language-csharp">public class SubTypeClassConverter : JsonConverter { // 重写CanConvert以支持SubTypeClassBase对象 public override bool CanConvert(Type objectType) { return objectType == typeof(SubTypeClassBase); } // 重写ReadJson以处理反序列化 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // 将JSON加载为JToken并获取“Type”标记 var token = JToken.Load(reader); var typeToken = token["Type"]; if (typeToken == null) throw new InvalidOperationException("无效对象"); // 根据“Type”值确定实际类型 var actualType = SubTypeClassBase.GetType(typeToken.ToObject<SubType>(serializer)); // 根据需要创建实际类型的实例 if (existingValue == null || existingValue.GetType() != actualType) { var contract = serializer.ContractResolver.ResolveContract(actualType); existingValue = contract.DefaultCreator(); } // 使用JSON数据填充实际类型 using (var subReader = token.CreateReader()) { serializer.Populate(subReader, existingValue); } return existingValue; } // 重写WriteJson以防止写入“Type”属性 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }</code>
透過此方法,JSON.NET會在序列化SubTypeClassBase物件時自動包含「Type」屬性,並使用SubTypeClassConverter根據指定的類型正確地反序列化JSON。
This revised response maintains the image, restructures the text for better readability and flow, and uses more concise language while retaining the original meaning. It oidoids direct word-for-replacement, op less repetitive tone.
以上是如何在沒有' $類型”字段的JSON.NET中序列化多態性對象?的詳細內容。更多資訊請關注PHP中文網其他相關文章!