是否存在仅解析 valid 对象并忽略 invalid 对象的内置方法(或技巧)?
非重复
问题Ignoring an invalid field when deserializing json in Json.Net 不能回答我的问题,因为它与日期时间类型的特定字段的自定义序列化程序有关。我正在寻找适用于任何属性和任何对象的通用解决方案。
换句话说,如果有什么无效的地方,那就忽略它并继续下一个条目。就json而言,文件是正确的,但是内容在某些地方可能与预期的类型不匹配。可以。
背景:文件包含许多工作流程的数组,并且单个受损条目不应破坏整个配置并实际上禁用它们。
这里有一个例子说明了我的意思。假设我有一个User
数组,但是一个条目而不是string
使用Name
会使用数组(它可能是无效值的任意组合,例如对象数组。
我想反序列化此数组,并忽略无法反序列化的条目。这意味着预期结果应该是两个用户,即 John 和 Tom 。
我尝试使用Error
处理程序,但这种方式无法正常工作。它不允许我跳过错误。
void Main()
{
var json = @"
[
{
'Name': 'John',
},
{
'Name': [ 'John' ]
},
{
'Name': 'Tom',
},
]
";
var users = JsonConvert.DeserializeObject<IEnumerable<User>>(json, new JsonSerializerSettings
{
Error = (sender, e) =>
{
e.Dump();
e.ErrorContext.Handled = true;
e.CurrentObject.Dump();
}
}).Dump();
}
class User
{
public string Name { get; set; }
}
答案 0 :(得分:2)
我这样解决了。不优雅。
var users = JsonConvert.DeserializeObject<IEnumerable<Object>>(json);
var usersList = users.ToList().Select(x =>
{
try { return JsonConvert.DeserializeObject<User>(JsonConvert.SerializeObject(x)); } catch { return null; }
}
).Where(x=> x != null).ToList<User>();
答案 1 :(得分:1)
关于我如何处理类似情况的一个很好的例子是,在JsonSerializerSettings
/ try
块内专门有一组不同的catch
配置。
例如:
JsonSerializerSettings jsonSetting = new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore };
您catch
之后,可以在try
部分中完成上述代码块,但未能完成JSON的解析。
您的try
块在上面的那个块内可能具有正常的错误行为:
jsonSetting = new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error };
提供类似的错误处理,当发生错误时,它将放入catch
块中以忽略丢失的字段。
但是,这取决于您是否可以跳过数据,还是要解析所有内容。确实是视情况而定,具体取决于您的实际JSON数据集。
将其放在try
/ catch
块上方,并根据需要使用jsonSetting
进行传递,具体取决于您的特定数据集。
编辑:只是为了强调,我确实要指出,您提供的示例并不是使用该方法的完美途径,但是它确实允许我跳过为空的数组,或者在我的情况下包含无效数据。它确实取决于您的数据集,但这可能是至少追求或考虑的有用途径。
答案 2 :(得分:1)
我知道这个问题有点老,但仅供参考:
您可以使用 JsonSerializerSettings 来处理解析错误。这允许您记录发现的任何错误,在这种情况下,将此类错误标记为已处理,以便继续解析:
new JsonSerializerSettings
{
Error = delegate(object sender, ErrorEventArgs args)
{
args.ErrorContext.Handled = true;
}
}