2017-10-27 13 views
3

すべてのnullプロパティ値を指定した文字列で置き換えるカスタムJSON.net IContractResolverを実装しようとしています。私は、この機能がシリアル化される型のメンバーの属性を介して利用可能であることを認識しています。これは私たちが検討している代替ルートです。カスタムJSON.netコントラクトリゾルバのプロパティ値をオーバーライド

これまでのリゾルバの実装は次のとおりです。 StringValueProviderは、問題に影響しないIValueProviderの単純な実装です。propertyの値を取得する方法を把握することができません。memberを提供するインスタンスのこのメソッドには知識がありません。 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

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

は、作業のデモです。あなたは 'StringValueProvider'でこれを行うことができます。そこでは、インスタンスと値の両方にアクセスでき、値がnullであるかどうかをチェックし、代わりにデフォルト値を使用できます。 – Evk

答えて

2

契約レゾルバはインスタンスに関係なく、タイプに関係します。値プロバイダはインスタンスに関係しています。契約レゾルバでは、プロパティタイプに基づいてプロパティに値プロバイダを適用するかどうかを決定します(たとえば、をstringプロパティにのみ使用する場合など)。次に、値プロバイダにプロパティ(コンストラクタで代入値とともに渡します)。値プロバイダでは、オブジェクトインスタンスから値を読み取り、nullであるかどうかを確認して適切な値の置換を実行できます。

コードは次のようになります:インスタンスが、この時点では存在しないので、それを行うには間違った場所だhttps://dotnetfiddle.net/PAZULK

+2

'PropertyInfo'をカスタム値プロバイダに渡すのではなく、Json.NETによって作成されたデフォルトの' IValueProvider'を渡して[decorator pattern](https://en.wikipedia.org/wiki/Decorator_pattern) [この回答](https://stackoverflow.com/a/35620248/3744182)または[this one](https://stackoverflow.com/a/32790038/3744182)のように。 Json.NETのバリュープロバイダは実行時に生成されるデリゲートを使用するため、パフォーマンスは純粋なリフレクションより優れているはずです。 – dbc

関連する問題