Reputation: 17415
A)
I have a DLL library include a class like the bellow code:
public class Thing
{
// OTHER_PROPERTIES
//..........................
[JsonProperty(Required = Required.Always)]
public bool IsBook { get; set; }
}
Assumption: I have not access to the source of the
Thing
class.
B)
And I have a JSON like this:
{
OTHER_PROPERTIES
}
Note: It has not a pair of name-value for
IsBook
Assumption: I wont change the
JSON
to includeIsBook
in it.
C)
If I run JsonConvert.DeserializeObject<Thing>(json);
then I get the following error:
Error: Required property not found in json ....
How can I write a custom code to solve the above error by observing the assumptions of the problem? (please read the above assumptions again before writing your answer.)
Upvotes: 2
Views: 8308
Reputation: 101533
You can use custom contract resolver to achieve that. For example:
public class Thing
{
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty(Required = Required.Always)]
public bool IsBook { get; set; }
}
class NeverRequiredContractResolver : DefaultContractResolver {
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
var prop = base.CreateProperty(member, memberSerialization);
prop.Required = Required.Default;
return prop;
}
}
And then:
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}",
new JsonSerializerSettings {
ContractResolver = new NeverRequiredContractResolver()
});
Of course you can assign resolver globally and not pass it to every DeserializeObject
:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new NeverRequiredContractResolver()
};
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}");
you can make only specific properties of specific classes non-required (and not all of them like in example above):
class CustomPropertyContractResolver : DefaultContractResolver {
private readonly Action<MemberInfo, JsonProperty> _propFixup;
public CustomPropertyContractResolver(Action<MemberInfo, JsonProperty> propFixup) {
_propFixup = propFixup;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
var prop = base.CreateProperty(member, memberSerialization);
_propFixup?.Invoke(member , prop);
return prop;
}
}
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new CustomPropertyContractResolver((member, prop) => {
if (member.DeclaringType == typeof(Thing) && member.Name == "IsBook") {
prop.Required = Required.Default;
}
})
};
var test = JsonConvert.DeserializeObject<Thing>("{\"Name\":\"some name\"}");
and overall adjust example above however you wish for your specific use case.
Upvotes: 6