C# JsonConvert在反序列化时不初始化属性,除非setter是泛型的

C# JsonConvert在反序列化时不初始化属性,除非setter是泛型的,c#,deserialization,getter-setter,jsonconvert,C#,Deserialization,Getter Setter,Jsonconvert,为什么当getter/setter不是泛型/默认值时,JsonConvert无法初始化属性值。 例如,JsonConvert将按其应该的方式反序列化以下类(或者更确切地说是属性“Value”)。假设我的Json文件包含Value=5,那么我的反序列化SomeObjectX对象的属性“Value”将设置为5: public class SomeClass { public int Value { get; set; } } 然而,如果我想让二传手更复杂一些,做一些特别的事情,那么它就不起

为什么当getter/setter不是泛型/默认值时,JsonConvert无法初始化属性值。
例如,JsonConvert将按其应该的方式反序列化以下类(或者更确切地说是属性“Value”)。假设我的Json文件包含Value=5,那么我的反序列化SomeObjectX对象的属性“Value”将设置为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
        {
            // Restrict range to Min/Max
            if (MaxValue < value)
                _value = MaxValue;
            else if (MinValue > value)
                _value = MinValue;
            else
                _value = value;
        }
    }
}
这是我在运行时得到的未初始化对象(请参见“Value”应该是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);
//创建并初始化对象
var param=new SomeClass();
参数MaxValue=10;
参数值=5;
//设置-使用或不使用都不会产生任何差异
JsonSerializerSettings设置=新的JsonSerializerSettings
{
TypeNameHandling=TypeNameHandling.All,
ObjectCreationHandling=ObjectCreationHandling.Replace
};
//序列化为Json
WriteAllText(@“e:\param.json”,JsonConvert.SerializeObject(param,settings));
//反序列化回对象
SomeClass obj=JsonConvert.DeserializeObject(File.ReadAllText(@“e:\param.json”),设置);

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


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

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

使用Newtonsoft.Json;
公共类
{
[JsonProperty(顺序=1)]
公共int最小值{get;set;}
[JsonProperty(顺序=2)]
public int MaxValue{get;set;}
私有整数值;
[JsonProperty(顺序=3)]
公共整数值
{
获取{返回_值;}
设置
{
//将范围限制为最小/最大
如果(最大值<值)
_值=最大值;
else if(最小值>值)
_值=最小值;
其他的
_价值=价值;
}
}
}
这样,JsonConvert将首先反序列化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;
        }
    }
}
公共类SomeClass
{
//建造师
公共类(int,value,int-minValue,int-maxValue)
{
MinValue=MinValue;
MaxValue=MaxValue;
//在最小值/最大值之后设置值
价值=价值;
}
公共int最小值{get;}
public int MaxValue{get;}
私有整数值;
公共整数值
{
获取{返回_值;}
设置
{
//将范围限制为最小/最大
如果(最大值<值)
_值=最大值;
else if(最小值>值)
_值=最小值;
其他的
_价值=价值;
}
}
}

json包中是否有一个设置可以控制字段是否优先于属性?您的json文档是什么样子的?@Neil,我不确定。刚刚编辑了Json输入的问题。为了避免耦合,我建议通过构造函数传递所有3个值,并在那里执行检查。然后,使模型本身不可变。至于手动排序,似乎可以使用
[Order]
属性。谢谢,我在下面根据您的输入添加了一个答案/示例。欢迎您检查并确认这是您的意思,谢谢:-)
// 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);
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;
        }
    }
}
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;
        }
    }
}