【问题标题】:Handling possible null value when converting JSON to C# class将 JSON 转换为 C# 类时处理可能的空值
【发布时间】:2019-05-22 11:38:23
【问题描述】:

在 UWP 中将 API 数据转换为 C# 类时遇到了一个有趣的问题。

我有一个返回图像尺寸的 API,如下所示:

{
    "height": "25",
    "width": "25"
}

我还有一个类,其属性与json2csharp.com 生成的 JSON 数据相匹配。

public class Image
{
    public int height { get; set; }
    public Uri url { get; set; }
    public int width { get; set; }
}

我正在使用类似这样的方法将 JSON 转换为 C# 类:

dynamic JsonData = JObject.Parse(JsonString);
Image img = JsonData.ToObject<Image>();

但是,如果 API 不知道高度或宽度,它会返回 null 而不是 int,如下所示:

{
    "height": null,
    "width": "25"
}

这显然会导致抛出异常,特别是这个错误消息:

Newtonsoft.Json.JsonSerializationException:将值 {null} 转换为类型“System.Int32”时出错

有没有办法解决这个问题或处理这种情况?

【问题讨论】:

  • 如果可以为您的整数获取 null,则将它们声明为可为 null 的整数
  • 让你int变量可空

标签: c# .net json uwp


【解决方案1】:

您可以通过添加? 使int 可以为空:

public class Image
{
    public int? height { get; set; }
    public Uri url { get; set; }
    public int? width { get; set; }
}

除了 json2csharp.com,QuickType 也可以帮你做到这一点:

public partial class Image
{
    [JsonProperty("height")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long? Height { get; set; }

    [JsonProperty("width")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Width { get; set; }
}

您必须自己添加 URL 属性。 QuickType 还会为您生成许多其他内容,例如 ParseStringConverter 自定义 JsonConverter

【讨论】:

    【解决方案2】:

    如果您希望为您的数据提供 null,请使用 nullbale 类型。将您的班级更改为:

    public class Image {
        public int? height { get; set; }
        public Uri url { get; set; }
        public int? width { get; set; }
    }
    

    【讨论】:

      【解决方案3】:

      另一种可行的方法:

      JsonConvert.SerializeObject(myObject, 
                                  Newtonsoft.Json.Formatting.None, 
                                  new JsonSerializerSettings { 
                                      NullValueHandling = NullValueHandling.Ignore
                                  });
      

      【讨论】:

        【解决方案4】:

        我同意其他建议可空整数的答案。这似乎是最干净的方法。如果没有可空整数选项,您确实可以尝试 NullValueHandling 选项并将整数保留为默认值。作为对此处其他答案的补充,我提供了一个使用 NullValueHandling 设置的示例。

        Fiddle (running example on dotnetfiddle)

        代码

        using System;
        using Newtonsoft.Json;
        
        public class Program
        {
            private static string JsonWithNull = @"{ 'height': '25', 'width': null }";
        
            public static void Main()
            {
                var settings = new JsonSerializerSettings()
                {
                    NullValueHandling = NullValueHandling.Ignore
                };
        
                Image image = JsonConvert.DeserializeObject<Image>(JsonWithNull, settings);
        
                Console.WriteLine("The image has a height of '{0}' and a width of '{1}'", image.height, image.width);
            }
        }
        
        public class Image
        {   
            public int height { get; set; }
            public Uri url { get; set; }
            public int width { get; set; }
        }
        

        【讨论】:

          【解决方案5】:

          考虑Newtonsoft.Json.NullValueHandling.Ignore 选项。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-09-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-07-08
            • 2023-04-07
            • 1970-01-01
            • 2018-12-06
            相关资源
            最近更新 更多