覆盖自定义JSON.net合约解析程序中的属性值

时间:2017-10-27 14:53:41

标签: c# json json.net

我正在尝试实现一个自定义的JSON.net IContractResolver,它将用指定的字符串替换所有null属性值。我知道这个功能可以通过序列化类型成员的属性获得;这是我们正在考虑的替代路线。

到目前为止我的解析器实现如下。 StringValueProvider是IValueProvider的一个简单实现,它不会影响问题,因为我不知道如何获取property的值,因为我不知道提供member的实例的方法。 1}}所以我不能将它作为参数传递给GetValue()(在代码示例中标记为WHAT-GOES-HERE?)。

有没有办法可以从memberproperty获得我需要的内容?

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;
    }
}

1 个答案:

答案 0 :(得分:7)

合同解析器与实例无关,它与类型有关。价值提供者关注实例。在合同解析程序中,您决定是否应根据属性类型将值提供程序应用于属性(例如,您可能只想在StringValueProvider属性上使用string?)然后,您使值提供程序存储对属性的引用(将其与替换值一起传递给构造函数)。在值提供程序中,您可以从对象实例中读取值,检查它是否为null并执行适当的值替换。

代码看起来像这样:

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