覆盖自定义 JSON.net 合同解析器中的属性值

时间:2023-04-25
本文介绍了覆盖自定义 JSON.net 合同解析器中的属性值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I am attempting to implement a custom JSON.net IContractResolver that will replace all null property values with a specified string. I'm aware that this functionality is available via attributes on member of types that get serialized; this is an alternative route that we're considering.

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

My resolver implementation so far is as follows. StringValueProvider is a simple implementation of IValueProvider that doesn't affect the problem, which is that I can't figure out how to get the value of property as I have no knowledge in this method of the instance that supplied member so I can't pass it in as an argument to GetValue() (marked as WHAT-GOES-HERE? in the code sample).

有没有一种方法可以让我从 memberproperty 获得我需要的东西?

Is there a way that I can get what I need from member or 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;
    }
}

推荐答案

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

The contract resolver is not concerned with instances, it is concerned with types. The value provider is concerned with instances. In the contract resolver, you decide whether the value provider should be applied to the property based on the property type (for example, maybe you only want to use a StringValueProvider on string properties?) Then, you make the value provider store a reference to the property (pass it in the constructor along with the substitution value). In the value provider, you can read the value from the object instance, check if it is null and do the appropriate value substitution.

代码应如下所示:

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

这篇关于覆盖自定义 JSON.net 合同解析器中的属性值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:调用 JsonConvert.DeserializeObject<T> 时缺少 System 下一篇:在 C# 中搜索 JSON.net 对象内的嵌套值

相关文章