![](/img/trans.png)
[英]Selectively exclude a property on one JSON serialization but not on another
[英]How to selectively exclude a property from serialization based on the parent class type
我正在使用Newtonsoft.JSON庫來序列化多個對象。 在某些情況下,我不想序列化屬性,因此我使用了ShouldSerialize前綴,該前綴在大多數情況下已大獲成功。 在一種情況下,如果屬性屬於特定類,我只想序列化它。
我已經嘗試過使用堆棧跟蹤,但是它只告訴我JSON對象正在調用ShouldSerialize方法。 我不需要知道應該調用ShouldSerialize的信息,我不需要知道ShouldSerialize屬於哪個父類,例如Parent.Child.ShouldSerialize。
在下面的代碼示例中,如何在使用JSON對象時確定父類名稱是什么?
class Foo
{
public SharedClass SomeProperty
{
get;
set;
}
}
class Bar
{
public SharedClass SomeProperty
{
get;
set;
}
}
class SharedClass
{
public string SomeValue
{
get;
set;
}
public bool ShouldSerializeSomeValue
{
//pseudo logic
return ClassName == "Foo";
}
}
正如Lasse Karlsen在評論中指出的那樣,如果您的SharedClass
沒有對其父級的引用,則ShouldSerializeSomeValue()
中的ShouldSerializeSomeValue()
方法將無法知道父級是什么。
但是,如果使用的是Json.Net 6.0 Release 6或更高版本,則可以通過使用自定義JsonConverter
作為有選擇地從共享類中忽略屬性的方法(而不是使用ShouldSerialize()
方法)來解決此問題,然后放置適當的父類內SharedClass
屬性上的[JsonConverter]
屬性,指示該實例應忽略哪些屬性。
這是更新后的示例類定義的外觀。 你會發現我已經標志着SharedClass
的實例Foo
指明應該使用稱為自定義轉換器OmitPropertiesConverter
省略SomeValue
財產。 Bar
上的SharedClass
實例不使用轉換器,因此該實例將被正常序列化。
class Foo
{
[JsonConverter(typeof(OmitPropertiesConverter), "SomeValue")]
public SharedClass Shared { get; set; }
}
class Bar
{
public SharedClass Shared { get; set; }
}
class SharedClass
{
public string SomeValue { get; set; }
public string SomeOtherValue { get; set; }
}
以下是OmitPropertiesConverter
的代碼。 它的構造函數接受propsToOmit
字符串,該字符串是一個逗號分隔的屬性名稱列表,該屬性名稱將從序列化中排除。 這將拆分為一個數組,以供以后在WriteJson
方法中使用。 該WriteJson
方法以SharedClass
值,將其轉換為JObject
,然后以編程除去它們是在屬性propsToOmit
陣列寫入之前JObject
到JsonWriter
。
class OmitPropertiesConverter : JsonConverter
{
string[] propsToOmit;
public OmitPropertiesConverter(string propsToOmit)
{
this.propsToOmit = propsToOmit.Split(new char[] {','},
StringSplitOptions.RemoveEmptyEntries);
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(SharedClass));
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
JObject jo = JObject.FromObject(value, serializer);
// Note: ToList() is needed here to prevent "collection was modified" error
foreach (JProperty prop in jo.Properties()
.Where(p => propsToOmit.Contains(p.Name))
.ToList())
{
prop.Remove();
}
jo.WriteTo(writer);
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
這是一個簡單的演示程序,顯示了運行中的轉換器:
class Program
{
static void Main(string[] args)
{
var root = new
{
Foo = new Foo
{
Shared = new SharedClass
{
SomeValue = "foo1",
SomeOtherValue = "foo2"
}
},
Bar = new Bar
{
Shared = new SharedClass
{
SomeValue = "bar1",
SomeOtherValue = "bar2"
}
}
};
string json = JsonConvert.SerializeObject(root, Formatting.Indented);
Console.WriteLine(json);
}
}
這是上述演示的輸出。 您會注意到,輸出中未包含Foo
內SharedClass
實例上的SomeValue
屬性,但它包含在Bar
內的實例上。
{
"Foo": {
"Shared": {
"SomeOtherValue": "foo2"
}
},
"Bar": {
"Shared": {
"SomeValue": "bar1",
"SomeOtherValue": "bar2"
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.