[英]Ignore property defined in interface when serializing using JSON.net
我有一個帶有這樣屬性的接口:
public interface IFoo {
// ...
[JsonIgnore]
string SecretProperty { get; }
// ...
}
我希望在序列化所有實現類時忽略SecretProperty
。 但似乎我必須在該屬性的每個實現上定義JsonIgnore
屬性。 有沒有辦法在JsonIgnore
為每個實現添加JsonIgnore
屬性的情況下實現這一點? 我沒有找到任何對我有幫助的序列化程序設置。
經過一番搜索,我發現了這個問題:
我拿了 Jeff JsonIgnoreAttribute
的代碼並添加了JsonIgnoreAttribute
檢測,所以它看起來像這樣:
class InterfaceContractResolver : DefaultContractResolver
{
public InterfaceContractResolver() : this(false) { }
public InterfaceContractResolver(bool shareCache) : base(shareCache) { }
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
var interfaces = member.DeclaringType.GetInterfaces();
foreach (var @interface in interfaces)
{
foreach (var interfaceProperty in @interface.GetProperties())
{
// This is weak: among other things, an implementation
// may be deliberately hiding an interface member
if (interfaceProperty.Name == member.Name && interfaceProperty.MemberType == member.MemberType)
{
if (interfaceProperty.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Any())
{
property.Ignored = true;
return property;
}
if (interfaceProperty.GetCustomAttributes(typeof(JsonPropertyAttribute), true).Any())
{
property.Ignored = false;
return property;
}
}
}
}
return property;
}
}
在我的JsonSerializerSettings
使用這個InterfaceContractResolver
,所有在任何接口中具有JsonIgnoreAttribute
屬性JsonIgnoreAttribute
被忽略,即使它們具有JsonPropertyAttribute
(由於內部if
塊的順序)。
在最新版本的 Json.NET 中,將[JsonIgnore]
應用於接口屬性現在可以正常工作並成功地防止它們被所有實現類型序列化,只要在聲明接口的同一類上聲明屬性即可。 不再需要自定義合同解析器。
例如,如果我們定義以下類型:
public interface IFoo
{
[JsonIgnore]
string SecretProperty { get; set; }
string Include { get; set; }
}
public class Foo : IFoo
{
public string SecretProperty { get; set; }
public string Include { get; set; }
}
然后以下測試在 Json.NET 11 和 12(可能還有更早的版本)中通過:
var root = new Foo
{
SecretProperty = "Ignore Me",
Include = "Include Me",
};
var json = JsonConvert.SerializeObject(root);
Assert.IsTrue(json == "{\"Include\":\"Include Me\"}");// Passes
我相信這是在 Json.NET 4.0.3中添加的,盡管發行說明中沒有明確提到JsonIgnore
:
新功能 - JsonObject 和 JsonProperty 屬性現在可以放置在接口上,並在序列化實現對象時使用。
(實現可以在JsonTypeReflector.GetAttribute<T>(MemberInfo memberInfo)
。)
我發現創建一個只包含我想要的屬性的 DTO 並將該對象序列化為 JSON 是最簡單的。 它創建了許多小的、特定於上下文的對象,但管理代碼庫要容易得多,我不必考慮我正在序列化的內容與我忽略的內容。
您應該在類名前添加[DataContract]
。
它將默認值從包含所有屬性更改為僅包含顯式標記的屬性。 之后,在要包含在 JSON 輸出中的每個屬性前添加“[DataMember]”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.