sách gpt4 ăn đã đi

c# - 在列表反序列化期间忽略缺失的类型

In lại Tác giả: Walker 123 更新时间:2023-11-30 16:00:55 24 4
mua khóa gpt4 giày nike

sử dụng TypeNameHandling.All 反序列化列表时,如果其中一项的类型命名空间丢失(序列化后删除),将导致 Error resolving type specified in JSON 错误。
我希望忽略这些项目,而将其余的留在后面。

Error = (sender, args) => { args.ErrorContext.Handled = true; hiện hữu JsonSerializerSettings 中做我正在寻找的,但当然会捕获所有错误。

是否有更简洁的方法来执行此操作,也许是通过我错过的序列化程序设置?

câu trả lời hay nhất

Bạn có thể sử dụng ErrorContext 的以下属性在 SerializationErrorCallback 里面限制要处理和忽略的错误类型:

  • ErrorEventArgs.ErrorContext.OriginalObject : 这获取导致错误的原始对象。 当由于类型名称无效而无法构造列表项时,OriginalObject将是列表本身。

    使用此属性,您可以检查是否 OriginalObjectlà một IList对于一些 T .

  • ErrorEventArgs.CurrentObject .获取引发错误事件的当前对象。序列化调用堆栈中的异常冒泡,每个级别的对象都可以尝试处理错误。

    CurrentObject == ErrorContext.OriginalObject 时,您将希望在最低级别处理它.

  • ErrorEventArgs.ErrorContext.Error - 获取抛出的实际异常。您将只想处理 serialization binder 抛出的异常。 .

现在,如何只检测和捕获那些由于失败的类型名称绑定(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 .

关于c# - 在列表反序列化期间忽略缺失的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39383098/

24 4 0
Walker 123
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress