在JSON反序列化期间使用set acessor

时间:2016-08-03 09:13:18

标签: c# json serialization

假设我有一个像这样的类的实例,我想序列化为JSON:

public class MyClass
{
    public MyClass() { }

    private List<string> texts;
    public List<string> Texts
    {
        get
        {
            return new List<string> { "You got me!" };
        }
        set
        {
            texts = value;
            Console.WriteLine("Setting property!");
        }
    }
}

我想确保在反序列化期间调用“文本”的set访问器,即确保MyClass中的私有属性“texts”被设置。但是,如果我运行一个小测试用例:

public void TestMyClass()
{
    var myClass = new MyClass();
    var jsonBefore = JsonConvert.SerializeObject(myClass);
    var jsonAfter = JsonConvert.DeserializeObject<MyClass>(jsonBefore);
}

set方法永远不会被调用,即反序列化后私有“texts”为null。如何确保在反序列化期间调用公共“文本”中的set访问器?

3 个答案:

答案 0 :(得分:1)

第一个原因是因为你使用的newtonsoft json序列化器与内置的.net one完全不同。

var json = new JavaScriptSerializer().Serialize(myClass);
var obj = new JavaScriptSerializer().Deserialize<MyClass>(json);

此代码可以正常运行。

第二个原因是你的get属性以及newtonsoft json序列化程序如何处理它,你有默认的列表创建(最好把它放到构造函数中,因为它现在没有任何意义)

如果您仍想使用现在实现的get,请使用JsonSerializerSettings.ObjectCreationHandling设置来自定义对象创建,

var jsonBefore = JsonConvert.SerializeObject(myClass);
var jsonAfter = JsonConvert.DeserializeObject<MyClass>(jsonBefore,  new JsonSerializerSettings
{
    ObjectCreationHandling = ObjectCreationHandling.Replace
});

答案 1 :(得分:1)

如果您不想在Texts属性中设置null,则可以为其设置默认值。 与private List<string> texts = new List<string>(){ "Default Value" };

一样

而不是

get
{
    return new List<string> { "You got me!" };
}

你应该使用

get
{
    return texts;
}

答案 2 :(得分:1)

序列化是将数据结构或对象状态转换为可以存储的格式(在我们的例子中是json)的过程。

对象状态由字段值组成,所有方法或其他行为逻辑都被忽略。

属性基本上是与支持字段一起使用的方法,因此它们不用于序列化/反序列化,因为它们不代表对象的状态。

在我们的案例中,字段texts使用反射进行序列化。然后它被直接反序列化,并且序列化程序可能甚至不知道该属性存在。