noelicus
noelicus

Reputation: 15055

How to override the "Required.Always" in newtonsoft json

This is following an example based on code from this question (albeit for Serialization). Is it possible to override all Required.Always to be Required.Default (i.e. "optional"), and allow me to deserialize an object regardless of the "required" attributes?

    public class OverrideToDefaultContractResolver : DefaultContractResolver
    {
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            var contract = base.CreateObjectContract(objectType);
            contract.ItemRequired = Required.Default;
            return contract;
        }
    }

    public class MyClass
    {
        [JsonProperty("MyRequiredProperty", Required = Required.Always, NullValueHandling = NullValueHandling.Ignore)]
        public string MyRequiredProperty { get; set; }
    }

    public static void Test()
    {
        var settings = new JsonSerializerSettings { ContractResolver = new OverrideToDefaultContractResolver() };
        MyClass obj = JsonConvert.DeserializeObject<MyClass>(@"{""Nope"": ""Hi there""}", settings);
        Console.WriteLine($"Json property: {obj.MyRequiredProperty}");
    }

Upvotes: 3

Views: 2891

Answers (1)

dbc
dbc

Reputation: 116786

In general, with Json.NET the precedence of settings is:

  1. An attribute applied to a property or parameter.
  2. An attribute applied to an object.
  3. Serialization settings applied to the serializer.

Your OverrideToDefaultContractResolver cancels Required attributes applied at the object level, but not at the individual property level. As the latter take precedence over the former, they need to be cancelled also. The following contract resolver does the job:

public class OverrideToDefaultContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(System.Reflection.MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        property.Required = Required.Default;
        return property;
    }

    protected override JsonObjectContract CreateObjectContract(Type objectType)
    {
        var contract = base.CreateObjectContract(objectType);
        contract.ItemRequired = Required.Default;
        return contract;
    }
    
    protected override JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo)
    {
        var property = base.CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo);
        property.Required = Required.Default;
        return property;
    }
}

Notes:

Demo fiddle here.

Upvotes: 7

Related Questions