Json.net 序列化/反序列化 abstract class

System.Text.Json 的解决方法:System.Text.Json 序列/反序列化 abstract class

用于检测类型的枚举

    public enum ItemTypes
    {
        Unknow = 0,
        Name,
        EnName,
        Mobile,
。。。

抽象类定义:

    [JsonConverter(typeof(RequirementConverter))]
    [Newtonsoft.Json.JsonConverter(typeof(RequirementConvertJsonNet))]
    public abstract class BaseItem
    {
        public virtual string ItemName { get; set; }

        public bool IsRequired { get; set; }

        public abstract ItemTypes Type { get; }

        public string Value { get; set; }
    }

子类定义:

    public class AddressItem : BaseItem
    {
        public override string ItemName { get; set; } = "地址";

        public override ItemTypes Type => ItemTypes.Address;
    }

用于检查类型的临时类:

        private class TypeDetectItem
        {
            [JsonProperty("Type")]
            public ItemTypes _Type { get; set; }

            [JsonIgnore]
            public ItemTypes Type => this._Type;
        }

ContractResolver 定义:

        private class BaseItemContractReslover : DefaultContractResolver
        {
            protected override JsonConverter ResolveContractConverter(Type objectType)
            {
                //因为 BaseItem 上指定了 Converter,
                //如果这里不返回 null 的话, 会一直循环执行, 导致 stackoverflow 异常.
                if (typeof(BaseItem).IsAssignableFrom(objectType) && !objectType.IsAbstract)
                    return null;
                return base.ResolveContractConverter(objectType);
            }
        }

Converter 定义:

   public class RequirementConvertJsonNet : JsonConverter
    {
        private static readonly JsonSerializerSettings setting = new JsonSerializerSettings()
        {
            ContractResolver = new BaseItemContractReslover()
        };

        public override BaseItem ReadJson(JsonReader reader, Type objectType, BaseItem existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var jobj = JObject.ReadFrom(reader);
            var detect = jobj.ToObject();

            var json = jobj.ToString();

            BaseItem o = detect.Type switch
            {
                ItemTypes.Name => JsonConvert.DeserializeObject(json, setting),
                ItemTypes.Credentials => JsonConvert.DeserializeObject(json, setting),
                ItemTypes.Address => JsonConvert.DeserializeObject(json, setting),
...
...
                _ => throw new NotImplementedException(),
            };

            return o;
        }

        public override void WriteJson(JsonWriter writer, BaseItem value, JsonSerializer serializer)
        {
            //这样写会报:Self referencing loop detected with type xxx
            //serializer.Serialize(writer, value, value?.GetType() ?? typeof(object));
            var json = JsonConvert.SerializeObject(value, value?.GetType() ?? typeof(object), setting);
            //writer.WriteRaw 会缺少逗号, writer.WriteValue 会把引号加上反斜杠。
            writer.WriteRawValue(json);
        }

你可能感兴趣的:(Json.net 序列化/反序列化 abstract class)