我正在使用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()
该类中的方法将无法知道父级是什么。
但是,如果您使用的是Json.Net 6.0 Release 6或更高版本,则可以通过使用自定义JsonConverter
方法来解决此问题,该方法是从共享类中有选择地省略属性(而不是使用ShouldSerialize()
方法),然后将[JsonConverter]
属性放在SharedClass
属性上在适当的父类中指示要为该实例省略哪些属性。
这是更新后的示例类定义的外观。您会注意到,我已将SharedClass
实例标记为打开,Foo
以指示它应使用称为OmitPropertiesConverter
忽略SomeValue
属性的自定义转换器。上的SharedClass
实例Bar
不使用转换器,因此该实例将被正常序列化。
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);
}
}
这是上述演示的输出。您会注意到,实例内部的SomeValue
属性未包含在输出中,但包含在内的实例中。SharedClass
Foo
Bar
{
"Foo": {
"Shared": {
"SomeOtherValue": "foo2"
}
},
"Bar": {
"Shared": {
"SomeValue": "bar1",
"SomeOtherValue": "bar2"
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句