Json.Net学习 异常处理

前端之家收集整理的这篇文章主要介绍了Json.Net学习 异常处理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Json.Net支持在序列化和反序列化的过程中进行异常处理。异常处理让您捕获一个异常,您可以选择是否处理它,继续序列化或者让异常抛给上一层,在你的应用程序中被抛出。

异常处理通过两个方法来定义:theError event on JsonSerializer 和 OnErrorAttribute

>Error Event

error event是一个建立在JsonSerializer 上的异常处理.当序列化或反序列化JSON时,任何有异常抛出的情况error event都会被触发.就像建立在JsonSerializer上的所有设置一样,它也可以在JsonSerializerSettings 上进行设置从而传递给JsonConvert的序列化方法

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

  2. List<DateTime> c;

  3. string strJson = @"[

  4. ""2010-12-19T00:00:00Z"",""I am not a date and will error!"",[

  5. 1

  6. ],null,""2011-01-01T00:00:00Z"",""2010-12-25T00:00:00Z""

  7. ]";

    JsonSerializerSettings setting = new JsonSerializerSettings();

  8. setting.Error = delegate(object o,ErrorEventArgs args)

  9. {

  10. errors.Add(args.ErrorContext.Error.Message);

  11. //错误标记为已处理,这样不会抛出异常

  12. args.ErrorContext.Handled = true;

  13. };

  14. setting.Converters.Add(new IsoDateTimeConverter());

  15. setting.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;

  16. setting.Formatting = Formatting.Indented;

  17. c= JsonConvert.DeserializeObject<List<DateTime>>(strJson,setting);

  18. foreach (DateTime t in c)

  19. {

  20. Console.WriteLine(t.ToString());

  21. }

  22. //2010-12-19 00:00:00

  23. //2011-01-01 00:00:00

  24. //2010-12-25 00:00:00

    foreach (string err in errors)

  25. {

  26. Console.WriteLine(err);

  27. }

  28. //The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.

  29. //Unexpected token parsing date. Expected String,got StartArray.

  30. //Cannot convert null value to System.DateTime.


在这个例子中我们把一个Json数组反序列化为一个DateTime的集合,在JsonSerializerSettings中有一个hander被赋值 成了error event,它用来记录error message,并标记这个error为已处理(handled).

反序列化JSON的结果是三个被成功反序列化的日期和三个error messages:一个是不正确的格式,"I am not adate and will error!",一个是嵌套了JSON数组,最后一个是null值,因为定义的list不允许有可空类型的DateTime.这个事件处理已经记录了这些 信息,Json.Net在序列化时继续进行(没有因为异常而停止),因为这些错误已经被标记为已处理。

值得注意的是,在Json.Net进行异常处理时,没有处理的异常将会被抛到上一层,并在它的每个parent触发事件,例如:在序列化若干对象的集合时,一个未处理的异常将被触发两次,首先在对象上,然后在集合上。这样就会让您在处理异常的时候,选择在它发生的地方,或者是它的一个parent上。

  1. JsonSerializer serializer = new JsonSerializer();
  2. serializer.Error += delegate(object send,ErrorEventArgs arg)
  3. {
  4. // only log an error once
  5. if (arg.CurrentObject == arg.ErrorContext.OriginalObject)
  6. errors.Add(arg.ErrorContext.Error.Message);
  7. };

如果您不是立即处理一个异常,仅仅是想针对它完成一次操作,您可以验证一下ErrorEventArg's CurrentObject是否等于OriginalObject.OriginalObject是抛出异常的对象,CurrentObject是事件被 触发的对象.他们只会在第一次(事件被OriginalObject触发时)相等.

>OnErrorAttribute

OnErrorAttribute的工作方式非常像其他Json.Net支持的.NET serialization attributes,简单地把它标记在带有正确参数(一个StreamingContext和一个ErrorContext)的方法上就可以使用了,与方法的名字没有关系。

  1. public class PersonError
  2. {
  3. private List<string> _roles;
  4.  
  5. public string Name { get; set; }
  6. public int Age { get; set; }
  7. public List<string> Roles
  8. {
  9. get
  10. {
  11. if (_roles == null)
  12. throw new Exception("Roles not loaded!");
  13.  
  14. return _roles;
  15. }
  16. set { _roles = value; }
  17. }
  18. public string Title { get; set; }
  19.  
  20. [OnError]
  21. internal void OnError(StreamingContext context,ErrorContext errorContext)
  22. {
  23. errorContext.Handled = true;
  24. }
  25. }
  1. PersonError person = new PersonError

  2. {

  3. Name = "George Michael Bluth",Age = 16,Roles = null,Title = "Mister Manager"

  4. };

    string json = JsonConvert.SerializeObject(person,Formatting.Indented);

    Console.WriteLine(json);

  5. /*

  6. {

  7. "Name": "George Michael Bluth","Age": 16,"Title": "Mister Manager"

  8. }

  9. */


在这个例子中,当_roles没有被设置值时访问Roles属性将会抛出一个异常.在序列化Roles属性时,异常处理的方法将设置error为handled,从而允许Json.Net继续序列化这个类。(注:上面这段代码在程序运行的时候还是会抛出异常,造成程序异常退出,不知道是什么原因.请明白的朋友指教.)

猜你在找的Json相关文章