2017-02-07 5 views
2

は、私はこのようなクラスを持っている:Newtonsoft JSON ShouldSerializeと継承

public class Foo 
{ 
    public int Bar { get; set;} 
} 

私はBar値を格納する必要があるので、このクラスは、NoSQLのデータベースに格納するために使用されます。しかし、私はこの値をAPIを通して公開したくありません。 私はFooから継承するクラスを作成しました。これはAPIから返されます。

私が見つけたドキュメントhereに従って、ShouldSerializeBarメソッドを作成しました。

public class Foo2 : Foo 
{ 
    public bool ShouldSerializeBar() 
    { 
     return false; 
    } 
} 

ただし、このメソッドは呼び出されません。これを達成するための回避策がありますか?

+0

あなたの要件を除いて、あなたは 'Foo'で試してみましたか? –

+0

ええ、それは、 'Foo'を直接シリアル化するときにうまくいきました。 –

+1

これは動作しない理由は、宣言型(別名 'Foo')でメソッドを検索し、親/基本クラスを検索しないためです。私は、以下の答え以外には別の方法がありません。 –

答えて

2
public class Foo 
{ 
    public int Bar { get; set;} 

    public virtual bool ShouldSerializeBar() 
    { 
     return true; 
    } 
} 

public class Foo2 : Foo 
{ 
    public override bool ShouldSerializeBar() 
    { 
     return false; 
    } 
} 
+1

それは私がやったことです。それは動作しますが、私は基本クラスでこのメソッドを追加することを避けたかったのです。とにかく、それは今のところトリックを行います;) –

1

あなたがIContractResolverを使用している場合Fooから継承する必要はありません。ドキュメントから

ShouldSerializeもIContractResolverを使用して設定することができます。 IContractResolverを使用してプロパティを条件付きでシリアル化するのは、 です.ShouldSerializeメソッドをクラス に配置したくない場合、またはクラスを宣言せずにできない場合に便利です。

あなたの場合、このようなものが動作するはずです。

public class ShouldSerializeContractResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     JsonProperty property = base.CreateProperty(member, memberSerialization); 

     if (property.DeclaringType == typeof(Foo) && property.PropertyName == "Bar") 
     { 
      property.ShouldSerialize = instance => false; 
     } 

     return property; 
    } 
} 

そしてあなたは、この新しいクラス(Foo2)とそのベースで仮想メソッドよりも侵入された場合、私は知りませんが、少なくともある

var foo = new Foo(); 
foo.Bar = 1; 

string json = JsonConvert.SerializeObject(foo, 
     Formatting.Indented, 
     new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver() }); 

のようにそれを使用することができます)別のオプション;)