2011-05-05 3 views
1

Newtonsoft.Json.Net35 버전 4.0.2.0을 사용하여 Null 값이 포함 된 ADO.NET DataTable을 deserialize하려고합니다. 직렬화가 잘 작동 : 값이 누락 된 경우Json.NET을 사용하여 Null 값을 포함하는 ADO.NET DataTable을 deserialize 할 수 있습니까?

[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"]); 
    } 

DeserializeObject는 "System.ArgumentException 예외 : 수 없습니다 'price'열을 null로 설정하십시오. 대신 DBNull을 사용하십시오. "

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

을 제외한 모든 정규 표현식 기반 잡든지처럼이 명확하게 취성 : 다음 해결 방법은 내 특정 JSON 작동합니다. 마지막으로

, 질문 :

  1. 이 버그인가요?
  2. Json.NET에는 많은 이벤트가 연결되어 있습니다. null 값이 발견 될 때 알림을 받고 명시 적으로 System.DBNull 값을 설정하는 방법이 있습니까? 그것은 다음과 같다 미리

감사

프랭크

답변

0

쉽게 Newtonsoft.Json.Converters.DataTableConverter

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

으로

dr[columnName] = reader.Value 

대체하여 고정 버그. 추적기에 issue을 입력했습니다.

+0

[고정] (http://json.codeplex.com/SourceControl/changeset/changes/60604). 감사합니다 제임스. – Frank

관련 문제