我正在尝试使用Newtonsoft.Json.Net35版本4.0.2.0反序列化包含空值的 ADO.NET 数据表。 序列化工作正常:
[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);
}
如果缺少值,反序列化工作正常:
[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"]);
}
但是,如果值显式为 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"]);
}
反序列化对象抛出"System.ArgumentException:无法将列'price'设置为空。请改用DBNull。 以下解决方法适用于我的特定 JSON:
var regex = new Regex(@",?""[_w]+"":null");
var nullless = regex.Replace(json, string.Empty);
var table = JsonConvert.DeserializeObject<DataTable>(nullless);
但像所有基于正则表达式的 kludges 一样,这显然是脆弱的。
最后,问题:
- 这是一个错误吗?
- Json.NET 有许多可以挂钩的事件。 有没有办法在遇到空值时收到通知,并将该值显式设置为 System.DBNull?
提前感谢,
弗兰克
看起来这是一个错误,可以通过替换轻松修复
dr[columnName] = reader.Value
跟
dr[columnName] = reader.Value ?? System.DBNull.Value
在Newtonsoft.Json.Converters.DataTableConverter中。 我在跟踪器中输入了一个问题。