Maison >développement back-end >C++ >Comment sérialiser les objets polymorphes dans json.net sans le champ '$ type'?
La désérialisation d'objets polymorphes dans JSON.NET est facile avec TypeNameHandling.Auto, mais que se passe-t-il si vous devez supprimer le champ « $type » ?
Méthode 1 : Renommer "$type" en un nom personnalisé
Malheureusement, les options intégrées de JSON.NET ne peuvent pas renommer "$type".
Méthode 2 : ajouter des informations de sous-type à la classe de base
Au lieu d'utiliser une classe conteneur pour contenir les informations de sous-type, ajoutez une propriété appelée « Type » à la classe de base (SubTypeClassBase) :
<code class="language-csharp">[JsonConverter(typeof(SubTypeClassConverter))] public class SubTypeClassBase { [JsonConverter(typeof(StringEnumConverter))] public SubType Type { get { return typeToSubType[GetType()]; } } }</code>
Cela garantit que les informations de sous-type sont toujours incluses lors de la sérialisation des objets de type SubTypeClassBase.
Désérialisation personnalisée
Pour désérialiser correctement JSON, créez un JsonConverter personnalisé (SubTypeClassConverter) qui lit la propriété "Type", identifie le type réel et désérialise en conséquence :
<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>
Avec cette approche, JSON.NET inclura automatiquement l'attribut « Type » lors de la sérialisation de l'objet SubTypeClassBase et utilisera SubTypeClassConverter pour désérialiser correctement JSON en fonction du type spécifié.
Cette réponse révisée conserve l'image, restructure le texte pour une meilleure lisibilité et fluidité, et utilise un langage plus concis tout en conservant le sens original. Elle évite le remplacement direct mot à mot, en optant pour des alternatives synonymes pour obtenir un langage plus naturel et plus naturel. ton moins répétitif.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!