Newtonsoft json将缺少int值的序列反序列化为空值而不是零

Vse*_*lod 1 c# json.net

可以这样调整JsonSerializerSettings吗?

(我猜不是)但仍有一些希望,因为我对他们的API不是很有经验.

默认情况下,我尝试丢失的所有设置都反序列化为0或导致异常.

   {
      "defaultCaptionLineNum": 6,
      "worksheets": {
        "0": { "name": "Ws1", "caption_ln": 6 },
        "1": { "name": "Ws2", "caption_ln": null },
        "2": { "name": "Ws3" },
        "3": { "name": "Ws4", "caption_ln": 5 },
      }
}
Run Code Online (Sandbox Code Playgroud)

目前默认情况下,Ws3的标题行(caption_ln)计算为0,我希望将其计算为null(如Ws2中所示).

我正在使用

jObject.ToObject<MyClass>(JsonSerializer.Create(settings));
Run Code Online (Sandbox Code Playgroud)

从JSON获取带有工作表(Ws)信息的对象(在没有序列化器的情况下尝试了它)

和任何变化Include,并Ignore在这里不作jObject在反序列化JSON缺少整数不同(与抛误差除外马上遗漏值)

var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
MissingMemberHandling = MissingMemberHandling.Ignore
};
Run Code Online (Sandbox Code Playgroud)

其他串行器设置似乎无关紧要.

UPD:MyObject MyClass的列表.

public class MyClass
{
    public class WorkSheet
    {
        [JsonProperty("name")]
        string wsName;

        [JsonProperty("caption_ln")]
        int? captionLineNumber;

        public WorkSheet(string name, int captionln)
        {
            wsName = name;
            captionLineNumber = captionln;
        }
    }
    private int _defaultCaptionLineNum;

    [JsonProperty("defaultCaptionLineNum")]
    public int DefaultCaptionLineNum { get => _defaultCaptionLineNum; }

    private Dictionary<int, WorkSheet> _worksheets = new Dictionary<int, WorkSheet>();

    [JsonProperty("worksheets")]
    public Dictionary<int, WorkSheet> Worksheets { get => _worksheets; set => _worksheets = value; }

    public MyClass()
    {           
        Console.WriteLine("New MyClass object created!");
    }
}
Run Code Online (Sandbox Code Playgroud)

dbc*_*dbc 5

您的问题是您的类型WorkSheet只有一个构造函数,它是参数化的:

public class WorkSheet
{
    public WorkSheet(string name, int captionln)
    {
        wsName = name;
        captionLineNumber = captionln;
    }

    // Remainder omitted
}
Run Code Online (Sandbox Code Playgroud)

正如文档页面ConstructorHandling Enumeration中所解释的,当没有无参数构造函数时,Json.NET将回退到单个参数化构造函数,这就是这里的情况.对于构造函数参数,Json.NET将按名称(模数情况)将JSON参数与构造函数参数进行匹配,反序列化为参数类型(如果存在)或传递默认值(如果不存在).由于"captionln"JSON中没有参数,因此captionLineNumber初始化为default(int),0.这解释了您所看到的问题.

要解决此问题,您可以更改captionln为类型int?:

public class WorkSheet
{
    public WorkSheet(string name, int? captionln)
    {
        wsName = name;
        captionLineNumber = captionln;
    }

    // Remainder omitted
}
Run Code Online (Sandbox Code Playgroud)

在这里工作小提琴#1 .

或者,您可以引入专用的特定于序列化的构造函数并将其标记为[JsonConstructor]:

public class WorkSheet
{
    [JsonConstructor]
    private WorkSheet() { }

    public WorkSheet(string name, int captionln)
    {
        wsName = name;
        captionLineNumber = captionln;
    }

    // Remainder omitted
}
Run Code Online (Sandbox Code Playgroud)

在这里示例小提琴#2 .

关于Json.NET中构造函数使用的相关问题: