PLN*_*ech 13 .net c# json jsonserializer json.net
我正在使用Newtonsoft的JsonSerializer来序列化一些类.
由于我想在序列化过程中省略我的类的一个字段,我将其声明如下:
[JsonIgnore]
public int ParentId { get; set; }
Run Code Online (Sandbox Code Playgroud)
这有效,但我现在面临一个新问题:在派生类中,我希望这个字段出现(并且只在这个特定的派生类中这样做).
我一直在浏览文档和互联网上的方法来覆盖子类中的这个设置(我想我需要类似的东西[JsonStopIgnore],但我找不到任何接近的东西).
JsonSerializer再次拿起这个属性吗?[JsonIgnore],但仅限于基类?Bri*_*ers 13
"覆盖" [JsonIgnore]属性行为的唯一方法是使用合约解析器,正如@Yuval Itzchakov在他的回答中很好地解释的那样.
但是,还有另一种可能对您有用的解决方案:[JsonIgnore]您可以ShouldSerializeParentId()在类中实现一个方法来控制ParentId属性是否被序列化,而不是使用属性.在基类中,使此方法返回false; 然后,重写派生类中的方法以返回true.(此功能在Json.Net中称为条件属性序列化.)
public class Base
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual bool ShouldSerializeParentId()
{
return false;
}
}
public class Derived : Base
{
public override bool ShouldSerializeParentId()
{
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
小提琴:https://dotnetfiddle.net/65sCSz
您可以通过创建自定义DefaultContractResolver并覆盖其CreateProperty方法来完成此操作.
例如,给定一个Foo基数和一个派生的Bar:
public class Foo
{
[JsonIgnore]
public string Name { get; set; }
public int Age { get; set; }
}
public class Bar : Foo
{ }
Run Code Online (Sandbox Code Playgroud)
您可以创建以下合同解析程序:
public class MyTypeContractResolver<T> : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member,
MemberSerialization
memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
property.Ignored = false;
property.ShouldSerialize = propInstance => property.DeclaringType != typeof (T);
return property;
}
}
Run Code Online (Sandbox Code Playgroud)
这将设置所有属性Ignored = false,然后按给定谓词分析它们:
propInstance => property.DeclaringType != typeof (T);
Run Code Online (Sandbox Code Playgroud)
在我们的情况下,这意味着"只有当它们不属于类型时才应序列化Foo"(因为Foo是DeclaryingType).
然后,当您要反序列化时,将合同解析器的实例传递给JsonSerializerSettings:
var bar = new Bar();
var result = JsonConvert.SerializeObject(bar,
new JsonSerializerSettings {ContractResolver = new MyTypeContractResolver<Bar>()});
Run Code Online (Sandbox Code Playgroud)
小智 6
我通过在派生类的属性上使用 new 关键字解决了同样的问题。
public class Foo
{
[JsonIgnore]
public int ParentId { get; set; }
}
public class Bar: Foo
{
[JsonProperty("ParentId")]
public new int ParentId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
您可以简单地ParentId在派生类中覆盖.
public new int ParentId
{
get { return base.ParentId; }
set { base.ParentId = value; }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4183 次 |
| 最近记录: |