【问题标题】:How to Deserialize Json with Composite Pattern - C#, Json如何使用复合模式反序列化 Json - C#、Json
【发布时间】:2022-01-07 09:33:17
【问题描述】:

由于我必须永远寻找答案,这将按原样工作,我将在此处提供一个示例,当您序列化和反序列化具有复合模式结构的对象时。

我的问题是反序列化这种类结构 (https://en.wikipedia.org/wiki/Composite_pattern):

abstract class BaseClass
{    
    public int Id { get; set; }
}

class Leaf : BaseClass
{
    public string Foo { get; set; }
}

class Composite : BaseClass
{
    public List<BaseClass> ClassList = new List<BaseClass>();
}

序列化通过使用:

var composite = new Composite();
JsonConvert.SerializeObject(composite, Formatting.Indented);

反序列化没有开箱即用。

【问题讨论】:

    标签: c# json.net composite


    【解决方案1】:

    反序列化的解决方案是构建一个CustomConverter:

    public class BaseClassJsonConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return typeof(BaseClass) == objectType;
            }
    
            public override object ReadJson(JsonReader reader, Type objectType,
                object existingValue, JsonSerializer serializer)
            {
                try
                {
                    var jObject = JObject.Load(reader);
    
                    var jsonSerializerSettings = new JsonSerializerSettings();
                    jsonSerializerSettings.Converters.Add(new BaseClassJsonConverter());
    
                    if (jObject.ContainsKey("Foo"))
                        return JsonConvert.DeserializeObject<Leaf>(jObject.ToString(), jsonSerializerSettings);
                    else if (jObject.ContainsKey("ClassList"))
                        return JsonConvert.DeserializeObject<Composite>(jObject.ToString(), jsonSerializerSettings);
                    else
                        throw new System.SystemException("Class not implemented");
                    return null;
                }
                catch (JsonReaderException)
                {
                    return null;
                }
            }
            public override bool CanWrite
            {
                get { return false; }
            }
    
            public override void WriteJson(JsonWriter writer, object value,
                JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
    

    与我发现的其他答案的主要区别在于,它们缺少将 ReadJson 中的设置再次放入 SeserialzieObject,这样它就无法处理递归结构 (Deserializing JSON to abstract class) 的反序列化。

    现在你可以用[JsonConverter(typeof(BaseConverter))]来装饰你的BaseClass

    或者你在设置中使用转换器调用反序列化:

    var jsonSerializerSettings = new JsonSerializerSettings();
    jsonSerializerSettings.Converters.Add(new BaseClassJsonConverter());
    JsonConvert.DeserializeObject<BaseClass>(jsonString, jsonSerializerSettings);
    

    【讨论】:

      猜你喜欢
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-07-13
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      相关资源
      最近更新 更多