【问题标题】:How to handle null/empty values in JsonConvert.DeserializeObject如何处理 JsonConvert.DeserializeObject 中的空值/空值
【发布时间】:2015-10-27 01:56:28
【问题描述】:

我有以下代码:

return (DataTable)JsonConvert.DeserializeObject(_data, (typeof(DataTable)));

然后,我尝试了:

var jsonSettings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
};

return (DataTable)JsonConvert.DeserializeObject<DataTable>(_data, jsonSettings);

返回线抛出错误:

{"将值 \"\" 转换为类型 'System.Double' 时出错。"}

许多在线解决方案建议使用可空类型创建自定义Class,但这对我不起作用。我不能指望 json 是某种格式。我无法控制列数、列类型或列名。

【问题讨论】:

  • 也许您应该只使用 LINQ to JSON,并获得 JObject 而不是创建 DataTable
  • 如果您需要转换DataTable,请使用专用转换器DataTableConverter
  • 您能否分享一个导致问题的 JSON 示例?
  • @Candide 使用return JsonConvert.DeserializeObject&lt;DataTable&gt;(_data, new DataTableConverter());时出现同样的错误

标签: c# json json.net


【解决方案1】:

您可以向JsonConvert.DeserializeObject 提供设置,告诉它如何处理空值,在这种情况下,还有更多:

var settings = new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore,
                        MissingMemberHandling = MissingMemberHandling.Ignore
                    };
var jsonModel = JsonConvert.DeserializeObject<Customer>(jsonString, settings);

【讨论】:

  • 这是一个完美的答案 - 我一直在寻找解决方案,终于找到了一个可行的解决方案。英雄状态。
  • MissingMemberHandling = MissingMemberHandling.Ignore 是默认值。无需添加。
  • 在我的类中反序列化原始类型 (long, int) 属性时出现错误。 json 来自我无法控制的不同 api。通用解决方案对我有用。谢谢托马斯
  • imo 这些应该是反序列化器的默认设置。默认情况下,它不应该因为遇到空值而破坏和破坏您的代码
【解决方案2】:

Thomas Hagström 的另一种解决方案是我的首选,它是在成员变量上使用 property 属性。

例如当我们调用一个 API 时,它可能返回也可能不返回错误消息,因此我们可以为 ErrorMessage 设置 NullValueHandling 属性:


    public class Response
    {
        public string Status;

        public string ErrorCode;

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string ErrorMessage;
    }


    var response = JsonConvert.DeserializeObject<Response>(data);

这样做的好处是隔离了数据定义(what)和反序列化(使用),反序列化不需要关心数据属性,这样两个人就可以一起工作,反序列化语句就会干净利落简单的。

【讨论】:

    【解决方案3】:

    您可以订阅“错误”事件并根据需要忽略序列化错误。

        static void Main(string[] args)
        {
            var a = JsonConvert.DeserializeObject<DataTable>("-- JSON STRING --", new JsonSerializerSettings
            {
                Error = HandleDeserializationError
            });
        }
    
        public static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
        {
            var currentError = errorArgs.ErrorContext.Error.Message;
            errorArgs.ErrorContext.Handled = true;
        }
    

    【讨论】:

    • 这个可以忽略错误。但是返回的DataTable 对象为空。
    • 你能发布 JSON 字符串,然后我会改变我的答案以更好地适应。
    【解决方案4】:

    ASP.NET 核心: 接受的答案完美无缺。但为了使答案适用于全局,在ConfigureServices 方法内的startup.cs 文件中写入以下内容:

        services.AddControllers().AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
        });
    

    答案已在 .Net Core 3.1 项目中进行了测试。

    【讨论】:

    • 如果没有关于您正在访问的服务的上下文,答案将是不完整和错误的。
    • @vivek86 我已经更新了答案。您可以删除您的反对票。
    • 这实际上是当代代码的一个很好的答案,因为设置全局 JSON 反序列化选项的问题已经浮出水面。
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    相关资源
    最近更新 更多