除非序列化器是通用的,否则反序列化时JsonConvert不会初始化属性

问题描述 投票:1回答:2

为什么当getter / setter不是通用/默认值时,JsonConvert无法初始化属性值。例如,JsonConvert将按需要反序列化以下类(或更确切地说,属性“ Value”)。假设我的Json文件包含Value = 5,那么我反序列化的SomeObjectX对象将其属性值设置为5:

public class SomeClass
{
    public int Value { get; set; }
}

但是,如果我想让设置器变得更复杂并且做一些特别的事情,那么它将无法正常工作。这是新的类:

public class SomeClass
{
    public int MinValue { get; set; }
    public int MaxValue { get; set; }

    private int _value;
    public int Value
    {
        get { return _value; }
        set
        {
            _value = value;

            // Restrict range to Min/Max
            if (MaxValue < value)
                _value = MaxValue;
            if (MinValue > value)
                _value = MinValue;
        }
    }
}

有关信息,这是我如何调用JsonConvert以反序列化为对象:

SomeClass SomeObjectX = JsonConvert.DeserializeObject<SomeClass>(File.ReadAllText(@"e:\someObject.json"), settings);

是否有办法使它正常工作?换句话说,如果我的Json包含10的初始化属性“ Value”,那么在反序列化时我应该将“ Value”设置为10。

编辑

序列化的Json文件如下所示:

{
  "MaxValue": 10,
  "MinValue": 0,
  "Value": 5
}

这里是我在运行时获取的未初始化对象(请注意,“ Value”应为0而不是5):enter image description here

这里是有关如何创建对象实例,对其进行初始化,将其保存到Json然后将其反序列化回对象的测试:

// Create and init object
var param = new SomeClass(); 
param.MaxValue = 10;
param.Value = 5;

// Settings - Not making any difference with or without
JsonSerializerSettings settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All,
    ObjectCreationHandling = ObjectCreationHandling.Replace
};

// Serialise into Json
File.WriteAllText(@"e:\param.json", JsonConvert.SerializeObject(param, settings));

// Deserialise back into object
SomeClass obj = JsonConvert.DeserializeObject<SomeClass>(File.ReadAllText(@"e:\param.json"), settings);
c# deserialization getter-setter jsonconvert
2个回答
3
投票

您面临的问题似乎与属性的反序列化顺序有关。您的原始模型包含ValueMaxValue属性之间的时间耦合,并且根据设置值的顺序,最终将在对象上得到不同的结果。

您应该能够使用属性上的[Order]属性来控制反序列化的顺序,但是我建议改为使模型不可变,并将所有3个值都传递给构造函数。这样,您还可以完全避免时间耦合,从而可以实现更好的设计。


0
投票

使用julealgon的输入回答我的问题。按照以下示例设置“ JsonProperty Order”属性(“ Value”需要使用最高的订单号):

using Newtonsoft.Json;

public class SomeClass
{
    [JsonProperty(Order = 1)]
    public int MinValue { get; set; }

    [JsonProperty(Order = 2)]
    public int MaxValue { get; set; }

    private int _value;

    [JsonProperty(Order = 3)]
    public int Value
    {
        get { return _value; }
        set
        {
            _value = value;

            // Restrict range to Min/Max
            if (MaxValue < value)
                _value = MaxValue;
            if (MinValue > value)
                _value = MinValue;
        }
    }
}

这样,JsonConvert将首先对MinValue和MaxValue进行反序列化,然后反序列化Value。

© www.soinside.com 2019 - 2024. All rights reserved.