繁体   English   中英

JsonConvert 在反序列化时不初始化属性,除非 setter 是通用的

[英]JsonConvert not initialising properties when deserializing unless setter is generic

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

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

但是,如果我希望 setter 更复杂一些并做一些特别的事情,那么它就行不通了。 这是新课程:

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

    private int _value;
    public int Value
    {
        get { return _value; }
        set
        {
            // Restrict range to Min/Max
            if (MaxValue < value)
                _value = MaxValue;
            else if (MinValue > value)
                _value = MinValue;
            else
                _value = value;
        }
    }
}

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

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

有没有办法让它发挥作用? 换句话说,如果我的 Json 包含一个 10 的初始化属性“Value”,那么反序列化时我应该将“Value”设置为 10。

编辑

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

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

这是我在运行时得到的非初始化对象(请参阅“值”是 0 而不是 5 应该的):
在此处输入图片说明

这是关于我如何创建对象实例、初始化它、将其保存到 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);

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

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

使用 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
        {
            // Restrict range to Min/Max
            if (MaxValue < value)
                _value = MaxValue;
            else if (MinValue > value)
                _value = MinValue;
            else
                _value = value;
        }
    }
}

这样 JsonConvert 将在反序列化 Value 之前首先反序列化 MinValue 和 MaxValue。

或者使用不可变属性:

public class SomeClass
{
    // Constructor
    public SomeClass(int, value, int minValue, int maxValue)
    {
        MinValue = minValue;
        MaxValue = maxValue;
        // Set value after Min/MaxValue
        Value = value;
    }
    public int MinValue { get; }
    public int MaxValue { get; }

    private int _value;
    public int Value
    {
        get { return _value; }
        set
        {
            // Restrict range to Min/Max
            if (MaxValue < value)
                _value = MaxValue;
            else if (MinValue > value)
                _value = MinValue;
            else
                _value = value;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM