Boomit
Boomit

Reputation: 187

How to throw a JsonSerializationException when a property is missing in the JSON and not nullable?

When deserializing a JSON string with missing properties, those properties in my class are populated with their default values. I want to change the JsonSerializerSettings so that, if a property is missing in the JSON and not nullable in the class, an exception is thrown. Conversely, when a property is nullable, it's not required.

I know it's possible with attributes but I want a generic setting.

JsonSerializerSettings settings = new JsonSerializerSettings();
MyParameters parms = JsonConvert.DeserializeObject<MyParameters>(json, settings);

Example:

public class MyParameters
{
    public string Message1 { get; set; }
    public string Message2 { get; set; }
    public int MyInt { get; set; }
    public int? MyNullableInt { get; set; }
}

The following JSON should be deserializable:

{
    "Message1": "A message",
    "MyInt ": 1
}

As result:

Message1 = "A message"
Message2 = null
MyInt = 1
MyNullableInt = null

But the following JSON should cause an exception because MyInt is missing:

{
    "Message1": "A message",
    "MyNullableInt": 1
}

Upvotes: 6

Views: 1555

Answers (1)

Brian Rogers
Brian Rogers

Reputation: 129697

You can use a custom ContractResolver to do what you want:

class NonNullablePropertiesRequiredResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty prop = base.CreateProperty(member, memberSerialization);
        Type propType = prop.PropertyType;
        if (propType.IsValueType && !(propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable<>)))
        {
            prop.Required = Required.Always;
        }
        return prop;
    }
}

Apply the resolver to your JsonSerializerSettings like this when you deserialize:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new NonNullablePropertiesRequiredResolver();
MyParameters parms = JsonConvert.DeserializeObject<MyParameters>(json, settings);

Working demo: https://dotnetfiddle.net/t56U2a

Upvotes: 3

Related Questions