Overriding property values ​​in JSON.net custom resolution

I am trying to implement a custom JSON.net IContractResolver that will replace all values ​​of a null property with a specified string. I know that this function is available through attributes for members of types that are serialized; this is an alternative route that we are considering.

My resolver implementation so far looks like this. StringValueProvider is a simple implementation of IValueProvider that does not affect the problem, and I cannot figure out how to get the value property, because I do not know this instance method that provided member, so I can not pass it as an argument GetValue()(marked as WHAT-GOES- HERE? In the sample code).

Is there a way to get what I need from memberor from property?

public class NullSubstitutionPropertyValueResolver : DefaultContractResolver
{
    private readonly string _substitutionValue;

    public NullSubstitutionPropertyValueResolver(string substitutionValue)
    {
        _substitutionValue = substitutionValue;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty result = base.CreateProperty(member, memberSerialization);

        PropertyInfo property = member as PropertyInfo;

        if (property == null)
        {
            return result;
        }

        // What do I use here to get the property value?
        bool isNull = property.GetValue(WHAT-GOES-HERE?) == null;

        if (isNull)
        {
            result.ValueProvider = new StringValueProvider(_substitutionValue);
        }

        return result;
    }
}
+4
source share
1 answer

A contract reporter does not deal with instances; it deals with types. The cost provider refers to instances. In the contract recognizer, you decide whether to use the value provider for the property based on the type of the property (for example, maybe you want to use only the StringValueProvideron properties string?). Then you make the value provider save the link to the property (pass it in the constructor along with the substitution value). In the value provider, you can read a value from an instance of an object, check if it is null, and perform an appropriate replacement of values.

The code should look something like this:

public class NullSubstitutionPropertyValueResolver : DefaultContractResolver
{
    private readonly string _substitutionValue;

    public NullSubstitutionPropertyValueResolver(string substitutionValue)
    {
        _substitutionValue = substitutionValue;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty result = base.CreateProperty(member, memberSerialization);

        PropertyInfo property = member as PropertyInfo;

        if (property.PropertyType == typeof(string))
        {
            result.ValueProvider = new StringValueProvider(property, _substitutionValue);
        }

        return result;
    }
}

public class StringValueProvider : IValueProvider
{
    private PropertyInfo _targetProperty;
    private string _substitutionValue;

    public StringValueProvider(PropertyInfo targetProperty, string substitutionValue)
    {
        _targetProperty = targetProperty;
        _substitutionValue = substitutionValue;
    }

    // SetValue gets called by Json.Net during deserialization.
    // The value parameter has the original value read from the JSON;
    // target is the object on which to set the value.
    public void SetValue(object target, object value)
    {
        _targetProperty.SetValue(target, value);
    }

    // GetValue is called by Json.Net during serialization.
    // The target parameter has the object from which to read the value;
    // the return value is what gets written to the JSON
    public object GetValue(object target)
    {
        object value = _targetProperty.GetValue(target);
        return value == null ? _substitutionValue : value;
    }
}

: https://dotnetfiddle.net/PAZULK

+3

Source: https://habr.com/ru/post/1688301/


All Articles