Reputation: 2961
I have the following class structure
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
{
}
How can I tell Json.NET to ignore errors for all the properties which have the IgnoreDeserializationErrorsAttribute
attribute.
I tried
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
}
}
});
but I am unable to populate the attributeDefined
variable inside the delegate.
Is this possible inside the error handler? or do I have to create a custom converter.
Upvotes: 0
Views: 1245
Reputation: 1193
There is a built-in OnError attribute that can be used for this purpose. See below the sample from the official documentation:
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;
}
}
Check Serialization Error Handling article for more info.
Upvotes: 1
Reputation: 5299
Let's you have the following classes for the sake of simplicity:
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
{
}
As you can notice I changed the type of
YetAnotherProperty
toint
and only this property is decorated withIgnoreDeserializationErrorsAttribute
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;
}
});
The code in the error handler reads the property that caused the error, checks if the property is decorated with IgnoreDeserializationErrorsAttribute
and sets the Handled
property of the ErrorContext accordingly.
Example: https://dotnetfiddle.net/zIj5RN
Upvotes: 0