Json.Net列表的反序列化期间调用属性getter,造成重复项目 [英] Json.Net calls property getter during deserialization of list, resulting in duplicate items

查看:193
本文介绍了Json.Net列表的反序列化期间调用属性getter,造成重复项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用json.net实施 Memento模式的WinForm应用程序。我使用的是纪念回滚上失败的数据库事务的对象。我得到的问题是,反序列化时的纪念品,吸气剂被称为而非制定者。让我来演示:

I'm using json.net to implement the memento pattern for a winform application. I'm using the memento to rollback an object on a failed database transaction. The problem I'm getting is that when deserializing the memento, the getter is called rather than the setter. Let me demonstrate:

class MyClass
{
    public int ID { get; set; }
    public string field1 { get; set; }
    public string field2 { get; set; }

    private List<SomeObject> _someObjects;
    public List<SomeObject> SomeObjects
    {
        get
        {
            if(_someObjects == null)
            {
                _someObjects = LoadSomeObjectsFromDB();
            }
            return _someObjects;
        }
        set
        {
            _someObjects = value;
        }
    }

    private List<AnotherObject> _anotherObjects;
    public List<AnotherObject> AnotherObjects
    {
        get
        {
            if(_anotherObjects == null)
            {
                _anotherObjects= LoadAnotherObjectsFromDB();
            }
            return _anotherObjects ;
        }
        set
        {
            _anotherObjects = value;
        }
    }
}



* 为MyObject SomeObject AnotherObject 延长相同的基类,模式

*MyObject, SomeObject, and AnotherObject extend the same base class, Model

你可以从样本类上面看,如果SomeObjects尚未加载,它使用的延迟加载从数据库加载它。现在当我序列化这个对象

As you can see from the sample class above, if SomeObjects is not loaded yet, it uses Lazy Loading to load it from the Database. Now When I serialize this object.

string memento = JsonConvert.SerializeObject(obj);



致使

Resulting in

{
  "ID": 1,
  "field1": "field 1",
  "field2": "field 2",
  "SomeObjects": [
    {
      "ID": 1,
    },
    {
      "ID": 2,
    },
    {
      "ID": 3,
    }
  ],
  "AnotherObjects": [
    {
      "ID": 4,
    },
    {
      "ID": 5,
    },
    {
      "ID": 6,
    }
  ]
}

随后反序列化。

MyObject obj = JsonConvert.DeserializeObject(memento, typeof(MyObject));



我得到下面的JSON

I get an object represented by the following JSON

{
  "ID": 1,
  "field1": "field 1",
  "field2": "field 2",
  "SomeObjects": [
    {
      "ID": 1,
    },
    {
      "ID": 2,
    },
    {
      "ID": 3,
    },
    {
      "ID": 1,
    },
    {
      "ID": 2,
    },
    {
      "ID": 3,
    }
  ],
  "AnotherObjects": [
    {
      "ID": 4,
    },
    {
      "ID": 5,
    },
    {
      "ID": 6,
    },
    {
      "ID": 4,
    },
    {
      "ID": 5,
    },
    {
      "ID": 6,
    }
  ]
}

SomeObjects AnotherObjects <$ C $项目过多C>列表取值

SomeObjects 调用getter时,这会导致列表进行初始化从DB则系列化列表追加到它。留下我在比预期列表中更多的项目。但是,如果我删除延迟加载部分

SomeObjects getter is called, which causes the List to initialize from the DB then the serialized list is Appended to it. Leaving me with more items in the list than desired. But if I remove the Lazy Loading portion

public List<SomeObject> SomeObjects
{
    get
    {
        /*if(_someObjects == null)
        {
            _someObjects = LoadSomeObjectsFromDB();
        }*/
        return _someObjects;
    }
    set
    {
        _someObjects = value;
    }
}



吸气剂仍称,但返回null。然后调用json.net与二传要与已经加入,正确数量的元素列表而如果吸气返回一个列表initalized,其追加到它永远不会调用的部份二传手。为什么差异,如果列表已经初始化,调用getter时,它是附加到。但如果没有进行初始化,设定器被调用,它与已填充有对象的列表进行初始化。有没有一种方法,使json.net只有一个通用的列表

The getter is still called, but returns null. Then json.net calls the setter with value being a list with the correct number of elements already added, whereas if the getter returns an initalized list, it appends to it never calling ths setter. Why the discrepancy, if a list is already initialized, the getter is called and it is appended to. But if not initialized, the setter is called and it is initialized with a list already filled with objects. Is there a way to make json.net only call the setter during deserialization of a generic List?

推荐答案

Json.Net有一个 ObjectCreationHandling 设置用于这一目的。尝试将它设置为替换,例如:

Json.Net has an ObjectCreationHandling setting for this purpose. Try setting it to Replace, e.g.:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;

MyObject obj = JsonConvert.DeserializeObject<MyObject>(memento, settings);



演示:的https:/ /dotnetfiddle.net/rkY1pt

这篇关于Json.Net列表的反序列化期间调用属性getter,造成重复项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆