2017-11-10 204 views
1

我已花了大約一天的時間。如果我有一個像JSON日期時間這樣的簡單對象集合,我可以將它正確地反序列化爲有效的對象和錯誤。對於更復雜的對象集合使用完全相同的方法會給我提供完全不同的結果:帶有問題的一個對象會停止正確創建所有其他對象。我嘗試了各種其他方法,例如使用JsonTextReader來瀏覽json查找對象,但它永遠不能通過錯誤的布爾值'tru'。JSON.NET中對象集合的錯誤處理行爲與簡單類型相比有所不同

基本上我想能夠反序列化所有的好值並跳過不好的值。

我在有關這種行爲差異的文檔中找不到任何內容。我也看了各種與解析和處理錯誤沒有運氣相關的stackoverflow文章。任何見解都非常感謝。

在這段代碼中,你會得到3個很好的日期和3個錯誤。

private void WorkingDeserializer() 
{ 
    List<string> errors = new List<string>(); 

    List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(
     @"[ 
     '2009-09-09T00:00:00Z', 
     'I am not a date and will error!', 
     [ 
     1 
     ], 
     '1977-02-20T00:00:00Z', 
     null, 
     '2000-12-01T00:00:00Z' 
     ]", 
     new JsonSerializerSettings 
     { 
      Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) 
      { 
       errors.Add(args.ErrorContext.Error.Message); 
       args.ErrorContext.Handled = true; 
      } 
     }); 
} 

在這段代碼中你沒有得到任何好的價值觀,錯誤

public class FeatureSwitch 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public bool Status { get; set; } 
} 

private void NonWorkingDeserializer() 
{ 
    List<string> errors = new List<string>(); 

    List<FeatureSwitch> c = JsonConvert.DeserializeObject<List<FeatureSwitch>>(
@"[ 
    { 
     'Name': 'TestSwitch1', 
     'Description': 'TestSwitch1_Desc', 
     'Status': false 
    }, 
    { 
     'Name': 'TestSwitch2', 
     'Description': 'bad format', 
     'Status': tru 
    }, 
    { 
     'Name': 'TestSwitch3', 
     'Description': 'should be good', 
     'Status': true 
    } 
]", new JsonSerializerSettings 
    { 
     Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) 
     { 
      errors.Add(args.ErrorContext.Error.Message); 
         args.ErrorContext.Handled = true; 
     } 
    }); 
} 

回答

3

這是因爲你破壞了在第二個例子中非法JSON語法JSON序列化。與第一個例子中一樣,您不打算解析日期時間或模型。

所以這個問題與複雜的對象無關。如果您在NonWorkingDeserializer中採用tru,並將其作爲您想在簡單日期時間序列化程序中出錯的值之一,則會得到相同的三個錯誤。錯誤列表中的三個錯誤與值tru的位置有關。他們不需要處理在不工作的反序列化程序json字符串中的3個模型對象。即使您嘗試使用其中的10個對象創建json字符串,您也會得到與值相關的3個錯誤tru

這是因爲您試圖使用破壞的語法反序列化JSON。在JSON

的布爾值的語法如下:

它包括真或假值。

var json-object-name = { string : true/false, .......} 

你正在寫與布爾語法JSON但不給予應有的價值

var json-object-name = { string : tru } 

字符串的語法如下:

var json-object-name = { string : "string value"} 

一個數組的語法如下:

[ value, .......] 

爲空的語法如下:

null 

爲一些語法如下:

var obj = {marks: 97} 

所屬的不同的值和它們的語法可以在JSON:

  • 字符串
  • 號碼
  • 對象陣列
  • TRUE
  • FALSE
  • NULL

,如果你做的是tru JSON字符串'tru'你會得到你想要的分析錯誤,不破JSON語法錯誤,你得到如

List<string> errors = new List<string>(); 

      List<FeatureSwitch> c = JsonConvert.DeserializeObject<List<FeatureSwitch>>(
     @"[ 
    { 
     'Name': 'TestSwitch1', 
     'Description': 'TestSwitch1_Desc', 
     'Status': false 
    }, 
    { 
     'Name': 'TestSwitch2', 
     'Description': 'bad format', 
     'Status': 'tru' 
    }, 
    { 
     'Name': 'TestSwitch3', 
     'Description': 'should be good', 
     'Status': true 
    } 
]", new JsonSerializerSettings 
     { 
      Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) 
      { 
       errors.Add(args.ErrorContext.Error.Message); 
       args.ErrorContext.Handled = true; 
      } 
     }); 

這給你你的FeatureSwitch列表的計數爲3,它給你一個單一的錯誤,因爲你沒有打破JSON本身。

你想要做的就像在json字符串裏面輸入一個Lorem Ipsum段落,然後在那裏丟棄一個有效的json的隨機位,並期望解串器能夠找到你的模型。

例如

List<string> errors = new List<string>(); 

     List<FeatureSwitch> c = JsonConvert.DeserializeObject<List<FeatureSwitch>>(
    @"[Maecenas nulla mauris, bibendum ac orci ut, consectetur egestas nisl. Morbi purus nibh, consectetur vel aliquet id, dictum vitae ante. 
    Maecenas cursus nunc orci, quis sollicitudin lorem dictum et. In molestie turpis tortor, eget aliquet nunc finibus sed. Proin vel dui nec eros pretium congue. 
    Pellentesque vitae tempor dui. Aliquam molestie, 
    { 
    'Name': 'TestSwitch1', 
    'Description': 'TestSwitch1_Desc', 
    'Status': false 
    } 
    dolor nec gravida molestie, felis neque vestibulum lorem, sed tempus arcu ligula at tortor. 
    Duis ac augue tincidunt odio convallis consectetur. Nam blandit mi ac purus convallis vulputate. Proin eget pretium lacus. Lorem ipsum dolor sit amet, 
    consectetur adipiscing elit. Praesent sem ante, gravida et dignissim egestas, commodo tincidunt sapien.]", new JsonSerializerSettings 
    { 
     Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) 
     { 
      errors.Add(args.ErrorContext.Error.Message); 
      args.ErrorContext.Handled = true; 
     } 
    }); 
+0

感謝您的回覆,我已將它標記爲已回答。我被指向jsonlint.com,可以看到json是無效的,我只需要有效的json作爲輸入。 – Sam

相關問題