c# - Newtonsoft json 将缺失的 int 值反序列化为空值而不是零

标签 c# json.net

是否可以通过这种方式调整 JsonSerializerSettings?

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

默认情况下,在所有设置下,我都尝试过丢失 int 反序列化为 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 },
      }
}

目前 Ws3 的默认字幕行 (caption_ln) 评估为 0,我希望它被评估为 null(如 Ws2 中)。

我正在使用

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

从 JSON 中获取带有工作表 (Ws) 信息的对象(也尝试过不使用序列化程序)

以及此处 IncludeIgnore 的任何变体不会使 jObject 以不同方式反序列化 json 中缺失的整数(除了立即抛出缺失值错误)

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

其他序列化器设置似乎无关紧要。

更新: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!");
    }
}

最佳答案

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

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

    // Remainder omitted
}

如文档页面中所述ConstructorHandling Enumeration , Json.NET 在没有无参构造函数的情况下会退回到单参数化构造函数,这里就是这种情况。对于构造函数参数,Json.NET 将按名称(模大小写)将 JSON 参数与构造函数参数匹配,如果存在则反序列化为参数类型,如果不存在则传递默认值。由于您的 JSON 中不存在 "captionln" 参数,captionLineNumber 被初始化为 default(int)0。这解释了您遇到的问题。

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

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

    // Remainder omitted
}

工作 fiddle #1 here .

或者,您可以引入一个私有(private)的特定于序列化的构造函数并用[JsonConstructor] 标记它。 :

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

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

    // Remainder omitted
}

示例 fiddle #2 here .

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

关于c# - Newtonsoft json 将缺失的 int 值反序列化为空值而不是零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52169522/

相关文章:

c# - UseIISPlatformHandler() 是否正确弃用为 UseIIS()?

c# - 在 C#/WPF/WinForms 中将 WMF 渲染为 BitMap 时如何启用抗锯齿?

c# - 忽略 Json.net 中的空字段

c# - DataContractJsonSerializer 和 JsonConvert 给出不同的结果

c# - 迭代 JObject 键

c# - HttpCookie.Name 是否与 Response.Cookies[string] 中的字符串相同?

c# - 使用双缓冲技术进行并发读写?

c# - Telerik MVC Extensions Grid - 如何将网格过滤器应用于初始 LINQ 查询或传递到数据库?

c# - 使用 JSON.NET 反序列化 Noda Time 的 LocalDateTime

c# - 在序列化之前将 string[] 转换为字符串