栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

具有多态子对象的类型的Json.Net序列化

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

具有多态子对象的类型的Json.Net序列化

在容器类中具有子类型信息存在问题,原因有两个:

  1. 当Json.NET读取包含的类时,无法访问容器类实例。
  2. 如果以后需要将
    SubTypeClassbase
    属性转换为列表,则将无处放置子类型信息。

相反,我建议将子类型信息作为属性添加到基类中:

[JsonConverter(typeof(SubTypeClassConverter))]public class SubTypeClassbase{    [JsonConverter(typeof(StringEnumConverter))] // Serialize enums by name rather than numerical value    public SubType Type { get { return typeToSubType[GetType()]; } }}

现在,每当可分配给其的对象被序列化时,自定义子类型枚举都将被序列

SubTypeClassbase
化。完成此操作后,对于反序列化,您可以创建一个
JsonConverter
将给定的json加载
SubTypeClassbase
到临时库中
JObject
,检查
"Type"
属性值,并将JSON对象反序列化为适当的类。

原型实现如下:

public enum SubType{    baseType,    Type1,    Type2,}[JsonConverter(typeof(SubTypeClassConverter))]public class SubTypeClassbase{    static readonly Dictionary<Type, SubType> typeToSubType;    static readonly Dictionary<SubType, Type> subTypeToType;    static SubTypeClassbase()    {        typeToSubType = new Dictionary<Type,SubType>()        { { typeof(SubTypeClassbase), SubType.baseType }, { typeof(SubTypeClass1), SubType.Type1 }, { typeof(SubTypeClass2), SubType.Type2 },        };        subTypeToType = typeToSubType.ToDictionary(pair => pair.Value, pair => pair.Key);    }    public static Type GetType(SubType subType)    {        return subTypeToType[subType];    }    [JsonConverter(typeof(StringEnumConverter))] // Serialize enums by name rather than numerical value    public SubType Type { get { return typeToSubType[GetType()]; } }}public class SubTypeClass1 : SubTypeClassbase{    public string AaaField { get; set; }}public class SubTypeClass2 : SubTypeClassbase{    public string ZzzField { get; set; }}public class SubTypeClassConverter : JsonConverter{    public override bool CanConvert(Type objectType)    {        return objectType == typeof(SubTypeClassbase);    }    public override bool CanWrite { get { return false; } }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        var token = JToken.Load(reader);        var typeToken = token["Type"];        if (typeToken == null) throw new InvalidOperationException("invalid object");        var actualType = SubTypeClassbase.GetType(typeToken.ToObject<SubType>(serializer));        if (existingValue == null || existingValue.GetType() != actualType)        { var contract = serializer.ContractResolver.ResolveContract(actualType); existingValue = contract.DefaultCreator();        }        using (var subReader = token.CreateReader())        { // Using "populate" avoids infinite recursion. serializer.Populate(subReader, existingValue);        }        return existingValue;    }    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        throw new NotImplementedException();    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/375965.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号