我正在尝试实现一个自定义的JSON.net IContractResolver,它将用指定的字符串替换所有null属性值。我知道这个功能可以通过序列化类型成员的属性获得;这是我们正在考虑的替代路线。
到目前为止我的解析器实现如下。 StringValueProvider是IValueProvider的一个简单实现,它不会影响问题,因为我不知道如何获取property
的值,因为我不知道提供member
的实例的方法。 1}}所以我不能将它作为参数传递给GetValue()
(在代码示例中标记为WHAT-GOES-HERE?)。
有没有办法可以从member
或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;
}
}
答案 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