序列化错误处理
json.net支持序列化和反序列化错误处理。错误处理可以捕捉错误并且可以选择处理错误且继续序列化或把从程序中错误抛出。
定义错误处理有两种方法:错误事件和错误修饰标签。
(一)事件处理
List<string> errors = new List<string>();
List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
""2009-09-09T00:00:00Z"",
""不能转换为日期"",
[
1
],
""1977-02-20T00:00:00Z"",
null,
""2000-12-01T00:00:00Z""
]",
new JsonSerializerSettings
{
Error =delegate(object obj,Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
errors.Add(args.ErrorContext.Error.Message);
args.ErrorContext.Handled = true;
},
Converters ={new IsoDateTimeConverter()}
});
foreach (DateTime dd in c)
{
Console.WriteLine(dd.ToString());
}
泛型列表c是一个日期类型的集合,其中有3个值不能成功序列化。如果不添加错误事件处理,则序列化出现错误。但通过错误事件处理,捕捉了其中的异常并使序列化继续下去。
输出结果:
/*
2009-9-9 0:00:00
1977-2-20 0:00:00
2000-12-1 0:00:00
*/
new JsonSerializerSettings
{
Error =delegate(object obj,Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
errors.Add(args.ErrorContext.Error.Message);
args.ErrorContext.Handled = true;
},
Converters ={new IsoDateTimeConverter()}
});
在系列化设置中,添加错误事件处理:
·Error属性是一个泛型委托:
EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> fun =
delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
errors.Add(args.ErrorContext.Error.Message);
args.ErrorContext.Handled = true;
};
这个例子中把一个json反序列化为一个日期集合。在序列化设置过程中为错误事件分配一个处理器,这个处理器用于记录错误信息并且标记这些错误是经过处理的。
这个json反序列化的结果是:有3个反序列化的日期对象和3个错误信息,
·该字符串未被识别为有效的 DateTime。有一个从索引 0 处开始的未知字。
·Unexpected token parsing date. Expected String, got StartArray.
·Cannot convert null value to System.DateTime.
(二)属性标签
json.net支持的这种属性标签很像其它.net序列化标签。只要用它来修饰方法并设置正确的参数即可。它的修饰的方法的参数有:StreamingContext和ErrorContext。而方法名无关。
public class PersonError
{
List<string> _list;
public string Name { get; set; }
public int Age { get; set; }
public List<string> HorseList
{
get
{
if (_list == null)
throw new Exception("Roles not loaded!");
return _list;
}
set { _list = value; }
}
public string Memo { get; set; }
[OnError]
internal void OnError(StreamingContext context, ErrorContext errorContext)
{
errorContext.Handled = true;
}
}
PersonError person = new PersonError
{
Name = "宋江",
Age = 32,
HorseList =null,
Memo = "天魁星"
};
string json = JsonConvert.SerializeObject(person, Formatting.Indented);
Console.WriteLine(json);
在这个例子中,访问HorseList属性时如果没有元素则会抛出异常。被属性标签修饰的方法会在序列化HorseList时处理错误并使序列化继续序列化类。
结果:
/*
{
"Name": "宋江",
"Age": 32,
"Memo": "天魁星"
}
*/