我对NewtonSoft Json.Net序列化有疑问。 我到处搜寻,但找不到解决方法。 SO中有一些问题与标题类似,但是没有一个问题。
我需要的是防止某些对象在某些条件下被序列化。
示例: 鉴于此类:
class A
{
B b;
}
我们可以通过写阻止B被序列化
class A
{
B b;
public bool ShouldSerializeb()
{
return false; //validate the condition you want.
}
}
但是,如果我们有多个B,则最终必须为每个B编写一个函数:
class A
{
B b;
B bb;
B bbb;
public bool ShouldSerializeb()
{
return false; //validate the condition you want.
}
public bool ShouldSerializebb()
{
return false; //validate the condition you want.
}
public bool ShouldSerializebbb()
{
return false; //validate the condition you want.
}
}
还有另一种方法:使用合同解析器
public class ShouldSerializeContractResolver : DefaultContractResolver
{
public new static readonly ShouldSerializeContractResolver Instance
= new ShouldSerializeContractResolver();
protected override JsonProperty CreateProperty(MemberInfo member,
MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (property.PropertyType == typeof(B))
{
property.ShouldSerialize =
instance =>
{
if (instance == null)
return false;
// The problem is that "instance" here is A and not B
// preventing the necessary validation
return false; //validate the condition you want.
};
}
return property;
}
}
问题:
是否有一种方法可以使“实例为” B”来验证其内部?
是否可以编写用于验证对象本身而非成员的函数? 像这样:
class B { public bool ShouldSerialize() { return false; //validate the condition you want. } }
谢谢 (我可能应该在github上发布它,但是我们习惯于将问题集中在SO上)
答案 0 :(得分:0)
您能为ShouldSerialize编写两个方法吗?
public bool ShouldSerialize(typeof(B))
{
return false;
}
或在B类中编写覆盖,然后将其称为B类:A,然后
Class B : A {
public overide bool ShouldSerialize()
{
return false;
}
}
Class A {
public bool ShouldSerialize(){
return true;
}
}
然后调用b.ShouldSerialize();或bb.ShouldSerialize();
值得一试,可能会误解了这个问题,但是嘿,其他人会及时知道的。
答案 1 :(得分:0)
是的,您可以在ContractResolver
中进行此操作。您拥有{{1}的instance
,并且拥有(A
类型的属性,因此您只需要在属性上询问B
就可以了实例中的值。这就是您要寻找的ValueProvider
。然后,您可以检查B
以确定是否要序列化该属性。
例如,如果类B
看起来像这样:
B
如果class B
{
public string Name { get; set; }
[JsonIgnore]
public bool IsHidden { get; set; }
}
为假,则可以在解析器中决定只想序列化B
:
IsHidden
这是一个有效的演示:https://dotnetfiddle.net/4MbQ0q
顺便说一句,我相当确定传递给protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (property.PropertyType == typeof(B))
{
property.ShouldSerialize = instance =>
{
if (instance == null) return false;
B b = (B)property.ValueProvider.GetValue(instance);
// validate the condition you want, for example:
return b != null && !b.IsHidden;
};
}
return property;
}
的{{1}}永远不会为空,因为询问instance
的属性是否应该是没有意义的如果没有ShouldSerialize
,则将其序列化。将支票存入那里并没有什么坏处,但我认为您不需要它。