2017-02-07 35 views
2

我有這樣一個類:Newtonsoft JSON ShouldSerialize和繼承

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

這個類是用來存儲在數據庫中的NoSQL,所以我需要存儲的Bar值。但是,我不想通過我的API公開這個值。 所以我創建了一個繼承自Foo的類,我將從我的API返回。

我通過以下文檔創建了方法ShouldSerializeBarhere

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

你並不需要,如果你使用IContractResolverFoo繼承。

從文檔

ShouldSerialize也可以使用IContractResolver設置。 如果您不想在類 上放置ShouldSerialize方法,或者您沒有聲明該類並且無法這樣做,則有條件地使用IContractResolver序列化屬性的方法是 。

在你的情況下,這樣的事情應該工作。

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

然後你就可以使用它像

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

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

雖然我不知道這是不是新的類(Foo2),並在其基礎的虛擬方法更具侵入性,至少是另一種選擇;)