2017-11-10 156 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

相关问题