sử dụng TypeNameHandling.All
反序列化列表时,如果其中一项的类型命名空间丢失(序列化后删除),将导致 Error resolving type specified in JSON
错误。
我希望忽略这些项目,而将其余的留在后面。
Error = (sender, args) => { args.ErrorContext.Handled = true;
hiện hữu JsonSerializerSettings
中做我正在寻找的,但当然会捕获所有错误。
是否有更简洁的方法来执行此操作,也许是通过我错过的序列化程序设置?
Bạn có thể sử dụng ErrorContext
的以下属性在 SerializationErrorCallback
里面限制要处理和忽略的错误类型:
现在,如何只检测和捕获那些由于失败的类型名称绑定(bind)而导致的异常?事实证明,Json.NET 的 DefaultSerializationBinder
抛出 JsonSerializationException
当无法加载类型时。但是,在许多其他情况下也会抛出相同的异常,包括格式错误的 JSON 文件。所以,介绍一个 ISerializationBinder
decorator从默认的 JSON binder 中捕获和捕获异常并将它们打包成特定的异常类型:
public class JsonSerializationBinder : ISerializationBinder
{
readonly ISerializationBinder binder;
public JsonSerializationBinder(ISerializationBinder binder)
{
if (binder == null)
throw new ArgumentNullException();
this.binder = binder;
}
public Type BindToType(string assemblyName, string typeName)
{
thử
{
return binder.BindToType(assemblyName, typeName);
}
catch (Exception ex)
{
throw new JsonSerializationBinderException(ex.Message, ex);
}
}
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
binder.BindToName(serializedType, out assemblyName, out typeName);
}
}
public class JsonSerializationBinderException : JsonSerializationException
{
public JsonSerializationBinderException() { }
public JsonSerializationBinderException(string message) : base(message) { }
public JsonSerializationBinderException(string message, Exception innerException) : base(message, innerException) { }
public JsonSerializationBinderException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
此外,在代码 Json.NET 的某个更高级别上,打包了 JsonSerializationBinderException
在另一个里面 JsonSerializationException
,因此在决定是否处理异常时,有必要查看内部异常以寻找必要类型的异常。以下设置完成这项工作:
var settings = new JsonSerializerSettings
{
SerializationBinder = new JsonSerializationBinder(new DefaultSerializationBinder()),
TypeNameHandling = TypeNameHandling.All, // Or Auto or Objects as appropriate
Error = (sender, args) =>
{
if (args.CurrentObject == args.ErrorContext.OriginalObject
&& args.ErrorContext.Error.InnerExceptionsAndSelf().OfType().Any()
&& args.ErrorContext.OriginalObject.GetType().GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IList<>)))
{
args.ErrorContext.Handled = true;
}
},
};
使用扩展方法:
public static class ExceptionExtensions
{
public static IEnumerable InnerExceptionsAndSelf(this Exception ex)
{
while (ex != null)
{
yield return ex;
ex = ex.InnerException;
}
}
}
演示 fiddle #1 đây .
请注意 ISerializationBinder
在 Json.NET 中引入 10.0.1 .在早期版本中,您的包装器必须继承自 SerializationBinder
并设置在 JsonSerializerSettings.Binder
.
演示 fiddle #2 đây .
Tôi là một lập trình viên xuất sắc, rất giỏi!