使用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 avoids direct word-for-word replacement, opting for synonymous alternatives to achieve a more natural and less repetitive tone.
以上是如何在没有'$type”字段的情况下序列化 JSON.NET 中的多态对象?的详细内容。更多信息请关注PHP中文网其他相关文章!