当属性类型为“对象”时,Newtonsoft.Json嵌套反序列化不会创建正确的对象类型

时间:2013-10-02 09:53:11

标签: c# serialization json.net

我有一组嵌套的.net类,具有不同的类型和继承。它试图模仿一系列项目。其中一个类是一个Cell类,它包含一个Object类型的Value属性(任何东西都可以到这里,甚至其他嵌套的单元格或行)。 Cell和Row类继承自基础ItemComponent类(复合模式)

我已经创建了一个自定义转换器来支持这个,并且在使用TypeNameHandling to All

后,我得到了反序列化正确的对象类型

我遇到的问题是嵌套的单元格。如果某个Cell的值是另一个单元格或行,则在Value属性中我只获取表示它的字符串,而不是填充值的序列化程序。到目前为止,这是我的代码

    public static object FromJson<T>(this string obj, T outputType)
    {
        return JsonConvert.DeserializeObject(obj, outputType as Type, new JsonConverter[1] { new ItemComponentJsonConverter() });
    }

public abstract class CustomJsonConverterBase<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jsonObject);

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var typeName = Type.GetType(jsonObject["$type"].ToString().Substring(0, jsonObject["$type"].ToString().IndexOf(',')));
        var target = Create(typeName ?? objectType, jsonObject);
        serializer.Populate(jsonObject.CreateReader(), target);
        // this is my attempt to make it work, but it doesn't. on first iteration it's populated, then I get a JObject with text again, and again
        if (target is Cell && (target as Cell).Value is JArray)
        {
            var innerCell = (target as Cell).Value.ToString().Substring(1, (target as Cell).Value.ToString().Length - 2).FromJson(typeof(Cell));
            (target as Cell).Value = innerCell;
        }
        return target;
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }
}

public class ItemComponentJsonConverter : CustomJsonConverterBase<ItemComponent>
{
    protected override ItemComponent Create(Type objectType, JObject jsonObject)
    {
        if (objectType == typeof(Row))
        {
            return new Row();
        }
        if (objectType == typeof(Entity))
        {
            return new Entity();
        }
        if (objectType == typeof(Cell))
        {
            return new Cell();
        }
        return (ItemComponent)Activator.CreateInstance(objectType);
    }
}

基本上我喜欢这样的,当我得到这样的东西时(我已经缩短了)我得到了正确的结构

细胞   .Value - &gt;实体               .childItems                   行                      .childItems                           细胞                               .Value - &gt; 124

等等

{
  "$type": "Arda.Lib.Models.Core.Cell, Arda.Lib",
  "childItems": {
    "$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
    "$values": []
  },
  "Value": {
    "$type": "Arda.Lib.Models.Core.Entity, Arda.Lib",
    "childItems": {
      "$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
      "$values": [
        {
          "$type": "Arda.Lib.Models.Core.Row, Arda.Lib",
          "childItems": {
            "$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
            "$values": [
              {
                "$type": "Arda.Lib.Models.Core.Cell, Arda.Lib",
                "childItems": {
                  "$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
                  "$values": []
                },
                "Value": 124,
                "Id": 247,

0 个答案:

没有答案