【问题标题】:Use set acessor during JSON deserialization在 JSON 反序列化期间使用 set acessor
【发布时间】:2016-08-03 21:09:14
【问题描述】:

假设我有一个这样的类的实例,我想将其序列化为 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!");
        }
    }
}

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

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

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

【问题讨论】:

    标签: c# json serialization


    【解决方案1】:

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

    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
    });
    

    【讨论】:

      【解决方案2】:

      如果您不想在Texts 属性中设置null,那么您可以为其设置默认值。 赞private List&lt;string&gt; texts = new List&lt;string&gt;(){ "Default Value" };

      而不是

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

      你应该使用

      get
      {
          return texts;
      }
      

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多