1
我正在嘗試使用Newtonsoft.Json.Net35版本4.0.2.0來反序列化包含空值的ADO.NET DataTable。序列化工作正常:如何使用Json.NET反序列化包含空值的ADO.NET DataTable?
[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"]);
}
然而,如果值是明確空:
[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:不能將Column'price'設置爲null,請改用DBNull。「以下的解決方法適用於我的特殊JSON:
var regex = new Regex(@",?""[_\w]+"":null");
var nullless = regex.Replace(json, string.Empty);
var table = JsonConvert.DeserializeObject<DataTable>(nullless);
但像所有基於正則表達式,組裝機這顯然是脆。
最後,問題:
- 這是一個錯誤?
- Json.NET有許多可以掛鉤的事件。是否有一種方法可以在遇到null值時得到通知,並顯式將值設置爲System.DBNull?
由於提前,
弗蘭克
[修正](http://json.codeplex.com/SourceControl/changeset/changes/60604)。謝謝詹姆斯。 – Frank 2011-05-07 02:53:03