NewtonSoft.JSON官方手册中文版【连载7】

即将推出本人原译的NewtonSoft.JSON官方手册中文版完整文档(.chm格式),敬请期待!

序列化错误处理

Json.NET支持序列化和反序列化过程中的错误处理。错误处理让你能够捕获错误,并选择是否处理错误,并继续序列化,或让错误在应用程序中冒泡并抛出错误。

通过两种方法定义了错误处理:在JsonSerializer上的Error事件以及OnErrorAttribute。

  • Error Event
  • OnErrorAttribute

Error事件

Error事件是一个事件处理器,能在JsonSerializer上找到。每当在序列化JSON或反序列化JSON时抛出了一个异常,就引发了此事件。就像在JsonSerializer上能找到的所有设置,Error也被设置在JsonSerializerSettings,并传递给JsonConvert上的序列化方法。

序列化错误处理

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, ErrorEventArgs args)
      {
          errors.Add(args.ErrorContext.Error.Message);
          args.ErrorContext.Handled = true;
      },
      Converters = { new IsoDateTimeConverter() }
  });
// 2009-09-09T00:00:00Z
// 1977-02-20T00:00:00Z
// 2000-12-01T00:00:00Z
// The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
// Unexpected token parsing date. Expected String, got StartArray.
// Cannot convert null value to System.DateTime.

在此示例中,我们把一个JSON对象反序列化为一个DataTimes的集合。在JsonSerializerSettings上,可以给Error事件分配一个处理函数,它会记录一条消息,并标记此错误已被处理。

反序列化此JSON的结果是三条成功的反序列化日期,以及三条错误消息:一要是针对格式错误的字符串(“I am not a date and will error”),一条是针对嵌套的JSON数组,一条是针对null值,因为列表不允许可空的DateTimes。此事件处理器记录了这三条消息,Json.NET没有停止反序列化JSON,是因为错误已被标记为已处理。

Json.NET中的错误处理,有一件需要注意的事情是,未处理的错误将会冒泡,并在它的每个你对象上引发错误事件上。例如,在序列化一个对象的集合时,一个未处理的错误将被引发两次,一次是针对此对象引发,另一次发生在集合上。从而你可以在发生错误的对象上或它的任一个父级上处理错误。

父级错误处理

List<string> errors = new List<string>();
JsonSerializer serializer = new JsonSerializer();
serializer.Error += delegate(object sender, ErrorEventArgs args)
{
  // only log an error once
  if (args.CurrentObject == args.ErrorContext.OriginalObject)
  {
      errors.Add(args.ErrorContext.Error.Message);
  }
};

如果你不能立即处理错误,只想针对它实施一次动作,则你可以检查ErrorEventArgs的CurrentObject是否等一OriginalObject。OriginalObject是抛出错误的对象,CurrentObject是引发事件的对象。只有在第一次针对OriginalObject引发事件时,这两者才是相等的。

OnErrorAttribute

OnErrorAttribute的作用方式很像Json.NET支持的其它.NET序列化特性。若要使用它,你只要把该特性放到方法上,并取用正确的参数:一个StreamingContext和一个ErrorContext。方法的名称是无关紧要的。

序列化错误处理特性

public class PersonError
{
  private List<string> _roles;
  public string Name { get; set; }
  public int Age { get; set; }
  public List<string> Roles
  {
      get
      {
          if (_roles == null)
          {
              throw new Exception("Roles not loaded!");
          }
          return _roles;
      }
      set { _roles = value; }
  }
  public string Title { get; set; }
  [OnError]
  internal void OnError(StreamingContext context, ErrorContext errorContext)
  {
      errorContext.Handled = true;
  }
}

在此示例如,当没有设置roles时,访问Roles属性将抛出一个异常。在序列化Roles的时候,此HandleError方法将把错误设置为已处理,并让Json.NET继续序列化类。

序列化错误处理示例

PersonError person = new PersonError
{
  Name = "George Michael Bluth",
  Age = 16,
  Roles = null,
  Title = "Mister Manager"
};
string json = JsonConvert.SerializeObject(person, Formatting.Indented);
Console.WriteLine(json);
//{
//  "Name": "George Michael Bluth",
//  "Age": 16,
//  "Title": "Mister Manager"
//}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值