如何处理 JsonConvert.DeserializeObject 中的 null/empty 值

How to handle null/empty values in JsonConvert.DeserializeObject

提问人:Kyle 提问时间:8/4/2015 更新时间:11/16/2023 访问量:169526

问:

我有以下代码:

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

然后,我尝试:

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

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

返回行抛出错误:

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

网上有很多解决方案建议使用可为 null 的类型创建自定义,但这对我不起作用。我不能指望json是某种格式。我无法控制列计数、列类型或列名称。Class

C# JSON json.net

评论

1赞 Jon Skeet 8/4/2015
也许你应该只使用 LINQ to JSON,并得到一个而不是创建一个?JObjectDataTable
0赞 Roland Mai 8/4/2015
如果需要转换,请使用专用转换器 DataTableConverterDataTable
2赞 dbc 8/4/2015
您能否分享导致问题的 JSON 示例?
0赞 Kyle 8/5/2015
@Candide 使用时出现相同错误return JsonConvert.DeserializeObject<DataTable>(_data, new DataTableConverter());

答:

5赞 DotNetHitMan 8/4/2015 #1

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

    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;
    }

评论

1赞 Kyle 8/5/2015
这完全忽略了错误。但返回的对象为 null。DataTable
0赞 DotNetHitMan 8/5/2015
你能发布JSON字符串吗,然后我会改变我的答案以更好地适应。
257赞 Thomas Hagström 3/17/2016 #2

您可以提供设置来告诉它如何处理 null 值(在本例中)等等:JsonConvert.DeserializeObject

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

评论

1赞 iTrout 11/19/2016
这是完美的答案 - 我一直在寻找解决方案,最后找到一个有效的解决方案。英雄状态。
7赞 Uylenburgh 9/25/2018
MissingMemberHandling = MissingMemberHandling.Ignore 为默认值。无需添加。
0赞 Satheesh K 6/24/2020
在我的类中反序列化原始类型(long,int)属性时,我遇到了一个错误。json来自我无法控制的不同api。通用解决方案对我有用。谢谢托马斯
3赞 SendETHToThisAddress 3/12/2021
imo 这些应该是解串器的默认设置。默认情况下,它不应该仅仅因为遇到 null 值而出错并破坏您的代码
34赞 Eynzhang 1/7/2020 #3

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)和反序列化(use),去序列化不需要关心数据属性,这样两个人就可以一起工作,并且反序列化语句将干净简单。

4赞 M Fuat 9/1/2020 #4

ASP.NET 核心: 公认的答案完美无缺。但是为了使答案全局适用,在 file inside 方法中写下以下内容:startup.csConfigureServices

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

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

评论

1赞 vivek86 12/26/2020
如果没有关于您正在访问哪些服务的上下文,答案将是不完整和错误的。
0赞 ZXX 5/20/2022
对于当代代码来说,这实际上是一个很好的答案,因为设置全局 JSON 反序列化选项的问题不断浮出水面。