我该如何反序列化使用Json.NET包含空值的ADO.NET数据表? [英] How can I deserialize an ADO.NET DataTable that contains null values using Json.NET?

查看:320
本文介绍了我该如何反序列化使用Json.NET包含空值的ADO.NET数据表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试使用 Newtonsoft.Json.Net35 版本4.0.2.0反序列化的ADO .NET数据表包含空值。序列化工作正常:

I am attempting to use Newtonsoft.Json.Net35 Version 4.0.2.0 to deserialize an ADO.NET DataTable that contains null values. Serialization works fine:

    [Test]
    public void SerializeDataTableWithNull()
    {
        var table = new DataTable();
        table.Columns.Add("item");
        table.Columns.Add("price", typeof(double));
        table.Rows.Add("shirt", 49.99);
        table.Rows.Add("pants", 54.99);
        table.Rows.Add("shoes"); // no price

        var json = JsonConvert.SerializeObject(table);
        Assert.AreEqual(@"["
            + @"{""item"":""shirt"",""price"":49.99},"
            + @"{""item"":""pants"",""price"":54.99},"
            + @"{""item"":""shoes"",""price"":null}]", json);
    }

反序列化工作正常,如果缺少值:

Deserialization works fine if values are missing:

    [Test]
    public void DerializeDataTableWithImplicitNull()
    {
        const string json = @"["
            + @"{""item"":""shirt"",""price"":49.99},"
            + @"{""item"":""pants"",""price"":54.99},"
            + @"{""item"":""shoes""}]";
        var table = JsonConvert.DeserializeObject<DataTable>(json);
        Assert.AreEqual("shirt", table.Rows[0]["item"]);
        Assert.AreEqual("pants", table.Rows[1]["item"]);
        Assert.AreEqual("shoes", table.Rows[2]["item"]);
        Assert.AreEqual(49.99, (double)table.Rows[0]["price"], 0.01);
        Assert.AreEqual(54.99, (double)table.Rows[1]["price"], 0.01);
        Assert.IsInstanceOf(typeof(System.DBNull), table.Rows[2]["price"]);
    }

然而,如果值是明确空:

If, however, values are explicitly null:

    [Test]
    public void DerializeDataTableWithExplicitNull()
    {
        const string json = @"["
            + @"{""item"":""shirt"",""price"":49.99},"
            + @"{""item"":""pants"",""price"":54.99},"
            + @"{""item"":""shoes"",""price"":null}]";
        var table = JsonConvert.DeserializeObject<DataTable>(json);
        Assert.AreEqual("shirt", table.Rows[0]["item"]);
        Assert.AreEqual("pants", table.Rows[1]["item"]);
        Assert.AreEqual("shoes", table.Rows[2]["item"]);
        Assert.AreEqual(49.99, (double)table.Rows[0]["price"], 0.01);
        Assert.AreEqual(54.99, (double)table.Rows[1]["price"], 0.01);
        Assert.IsInstanceOf(typeof(System.DBNull), table.Rows[2]["price"]);
    }

DeserializeObject抛出System.ArgumentException:无法设置列'价格'为空请使用DBNull的了吧。以下解决方法适用于我的特殊JSON:

DeserializeObject throws "System.ArgumentException : Cannot set Column 'price' to be null. Please use DBNull instead." The following workaround works for my particular JSON:

        var regex = new Regex(@",?""[_\w]+"":null");
        var nullless = regex.Replace(json, string.Empty);
        var table = JsonConvert.DeserializeObject<DataTable>(nullless);

但像所有普通EX pression为基础的组装机这显然是易碎的。

but like all regular expression-based kludges this is clearly brittle.

最后,问题:

  1. 这是一个错误?
  2. Json.NET有许多事件,可以直接连接。有没有办法得到通知时,当一个空值遇到并明确其值设置为System.DBNull?

在此先感谢,

弗兰克

推荐答案

看起来这是一个很容易通过更换错误

It looks like this is a bug which is easily fixed by replacing

dr[columnName] = reader.Value

dr[columnName] = reader.Value ?? System.DBNull.Value

Newtonsoft.Json.Converters.DataTableConverter 。我已经进入了一个问题的跟踪器。

in Newtonsoft.Json.Converters.DataTableConverter. I have entered an issue in the tracker.

这篇关于我该如何反序列化使用Json.NET包含空值的ADO.NET数据表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆