json.Net +处理基于属性的反序列化错误
本文关键字:属性 反序列化 错误 Net 处理 于属性 json | 更新日期: 2023-09-27 18:16:18
我有以下的类结构
public class Parent
{
public int SomeProperty { get; set; }
[IgnoreDeserializationErrors] // This attribute can be here
public FirstLevel FirstLevelProperty { get; set; }
}
public class FirstLevel
{
public int AnotherProperty { get; set; }
[IgnoreDeserializationErrors] // Or this can be here
public SecondLevel SecondLevelProperty { get; set; }
}
public class SecondLevel
{
public int OneMoreProperty { get; set; }
[IgnoreDeserializationErrors] //Or Here
public string YetAnotherProperty { get; set; }
}
And this Attribute:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class IgnoreDeserializationErrorsAttribute : Attribute
{
}
如何告诉Json。忽略所有具有IgnoreDeserializationErrorsAttribute
属性的属性的错误。
我试着
var deserialized = JsonConvert.Deserialize<Parent>(someJson, new JsonSerializerSettings
{
Error = (s, e) => {
bool attributeDefined = true;//TODO: How do I get the properties attributes here.
if (attributeDefined)
{
e.ErrorContext.Handled = true
}
}
});
但是我无法在委托中填充attributeDefined
变量。
这在错误处理程序中是可能的吗?或者我必须创建一个自定义转换器
有一个内置的OnError属性可用于此目的。下面是官方文档中的示例:
public class PersonError
{
private List<string> _roles;
public string Name { get; set; }
public int Age { get; set; }
public List<string> Roles
{
get
{
if (_roles == null)
{
throw new Exception("Roles not loaded!");
}
return _roles;
}
set { _roles = value; }
}
public string Title { get; set; }
[OnError]
internal void OnError(StreamingContext context, ErrorContext errorContext)
{
errorContext.Handled = true;
}
}
查看序列化错误处理文章了解更多信息。
为了简单起见,让我们使用以下类:
public class Parent
{
public int SomeProperty { get; set; }
public FirstLevel FirstLevelProperty { get; set; }
}
public class FirstLevel
{
public int AnotherProperty { get; set; }
public SecondLevel SecondLevelProperty { get; set; }
}
public class SecondLevel
{
public int OneMoreProperty { get; set; }
[IgnoreDeserializationErrors]
public int YetAnotherProperty { get; set; }
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class IgnoreDeserializationErrorsAttribute : Attribute
{
}
您可以注意到,我将
YetAnotherProperty
的类型更改为int
,并且只有该属性使用IgnoreDeserializationErrorsAttribute
进行装饰
var someJson = "{'"SomeProperty'": 3, '"FirstLevelProperty'": {'"AnotherProperty'": 35, '"SecondLevelProperty'": {'"OneMoreProperty'": 359, '"YetAnotherProperty'": '"test'"}}}";
var deserialized = JsonConvert.DeserializeObject<Parent>(someJson, new JsonSerializerSettings
{
Error = (s, e) =>
{
bool attributeDefined = false;
if (e.CurrentObject == null) return;
PropertyInfo property = e.CurrentObject.GetType().GetProperty(e.ErrorContext.Member.ToString());
if (property == null) return;
var attr = property.GetCustomAttribute(typeof (IgnoreDeserializationErrorsAttribute));
if (attr != null) attributeDefined = true;
if (attributeDefined) e.ErrorContext.Handled = true;
}
});
错误处理程序中的代码读取导致错误的属性,检查该属性是否用IgnoreDeserializationErrorsAttribute
装饰,并相应地设置ErrorContext的Handled
属性。
示例:https://dotnetfiddle.net/zIj5RN