简体   繁体   English

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

[英]Newtonsoft json deserialise missing int values as nulls instead of zero

Is it possible to adjust JsonSerializerSettings that way? 是否可以通过这种方式调整JsonSerializerSettings?

(I guess not) but still have some hope, cause I'm not very experienced with their API. (我想不是),但是仍然有一些希望,因为我对他们的API不太了解。

By default and with all settings I've tried missing int either deserialized to 0 or causing exception. 默认情况下,使用所有设置,我尝试将int反序列化为0或导致异常。

Example

   {
      "defaultCaptionLineNum": 6,
      "worksheets": {
        "0": { "name": "Ws1", "caption_ln": 6 },
        "1": { "name": "Ws2", "caption_ln": null },
        "2": { "name": "Ws3" },
        "3": { "name": "Ws4", "caption_ln": 5 },
      }
}

Currently by default caption line (caption_ln) of Ws3 evaluated to 0, I want it to be evaluated to null (as in Ws2). 当前默认情况下,Ws3的字幕行(caption_ln)评估为0,我希望将其评估为null(与Ws2一样)。

I'm using 我正在使用

jObject.ToObject<MyClass>(JsonSerializer.Create(settings));

to get object with worksheet(Ws) information from JSON (tried it without serializer as well) 从JSON获取带有工作表(Ws)信息的对象(也尝试了不使用序列化器的情况)

and any variations of Include and Ignore here don't make jObject deserialize missing ints in json differently (with the exception of throwing error right away for missing values) 并且IncludeIgnore任何变体都不会使jObject对json中缺少的int进行反序列化(例外是立即为丢失的值抛出错误)

var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
MissingMemberHandling = MissingMemberHandling.Ignore
};

Other serializer settings seem to be irrelevant. 其他串行器设置似乎无关紧要。

UPD: Listing of MyObject MyClass. 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!");
    }
}

Your problem is that your type WorkSheet has only one constructor, which is parameterized: 您的问题是您的WorkSheet类型只有一个构造函数,该构造函数已参数化:

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

    // Remainder omitted
}

As explained in the documentation page ConstructorHandling Enumeration , Json.NET will fall back to a single parameterized constructor when there is no parameterless constructor, which is the case here. 如文档页面ConstructorHandling Enumeration中所述 ,当没有无参数构造函数时,Json.NET将退回到单个参数化构造函数,在这种情况下就是这样。 For the constructor arguments, Json.NET will match the JSON parameters to constructor arguments by name (modulo case), deserializing to the argument type if present or passing a default value if not present . 对于构造函数参数,Json.NET将按名称(取模)将JSON参数与构造函数参数匹配,如果存在则反序列化为参数类型, 如果不存在则传递默认值 And since there is no "captionln" parameter present in your JSON, captionLineNumber gets initialized to default(int) , which is 0 . 而且,由于您的JSON中没有"captionln"参数,因此captionLineNumber初始化为default(int)0 This explains the problem you are seeing. 这说明了您遇到的问题。

To fix the problem, you can change captionln to be of type int? 要解决此问题,您可以将captionln更改为int?类型int? :

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

    // Remainder omitted
}

Working fiddle #1 here . 在这里工作#1。

Alternatively, you could introduce a private serialization-specific constructor and mark it with [JsonConstructor] : 另外,您可以引入专用于序列化的私有构造函数,并使用[JsonConstructor]标记:

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

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

    // Remainder omitted
}

Sample fiddle #2 here . 在这里样本小提琴2。

Related questions on constructor use in Json.NET: 有关在Json.NET中使用构造函数的相关问题:

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

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