如何在序列化期间忽略我不拥有的子类的属性?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在序列化期间忽略我不拥有的子类的属性?相关的知识,希望对你有一定的参考价值。
我有一个班级Tempo
。我可以自由改变:
public class Tempo
public Period Period get; set;
public int Value get; set; // in fact int should be a T here if it matters.
// more properties here
Period
是一个来自外部依赖的类,我无法改变。
public class Period
public DateTime Start get; set;
public DateTime End get; set;
public int Count get; set;
public string Foo get; set;
// more properties here
Period
是一个庞大的类,有很多属性,我不想序列化。所以对我来说没有甜蜜的[JsonIgnore]
。从Period
我想只保留Start
和End
属性。
我试图使用DefaultContractResolver
但没有成功:
class TempoResolver : DefaultContractResolver
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
var props = base.CreateProperties(type, memberSerialization);
return props
.Where(p => p.PropertyName != "Period") // how to filter subclass?
.ToList();
我试图使用JsonConverter
没有成功:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
var jo = new JObject();
var type = value.GetType();
jo.Add("type", type.Name);
foreach (var prop in type.GetProperties().Where(x => x.CanRead))
object propVal = prop.GetValue(value, null);
if (propVal != null)
jo.Add(prop.Name,
JToken.FromObject(propVal, serializer)); // how to filter subclass?
jo.WriteTo(writer);
在这两种情况下,我不知道如何过滤Period
。如何在序列化期间忽略我不拥有的子类的属性?
注意:
- 我使用C#6
- 我使用JSON.NET
创建子类:
public class Periodic
public DateTime Start get; set;
public DateTime End get; set;
使用此代码的自定义转换器:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
Periodic periodic = (Periodic)value;
JToken t = JToken.FromObject(periodic);
t.WriteTo(writer);
您可以为JsonConverter
类创建强类型Period
:
public class PeriodConverter : JsonConverter<Period>
public override void WriteJson(JsonWriter writer, Period period, JsonSerializer serializer)
writer.WriteStartObject();
writer.WritePropertyName(nameof(Period.Start));
writer.WriteValue(period.Start);
writer.WritePropertyName(nameof(Period.End));
writer.WriteValue(period.End);
writer.WriteEndObject();
public override Period ReadJson(JsonReader reader, Type objectType, Period existingValue, bool hasExistingValue,
JsonSerializer serializer)
throw new NotSupportedException();
用法:
var tempo = new Tempo
Period = new Period
Start = DateTime.Now.AddDays(-1),
End = DateTime.Now.AddHours(-1),
Count = 42,
Foo = "Foo"
,
Value = 42
;
var result = JsonConvert.SerializeObject(tempo, new PeriodConverter());
var regularJson = JsonConvert.SerializeObject(tempo);
regularJson
将拥有Period
的所有房产:
“周期”: “开始”: “2019-04-08T12:21:39.1525361 + 03:00”, “结束”: “2019-04-09T11:21:39.1535328 + 03:00”, “计数”: 42, “富”: “富”, “值”:42
和result
只期望:
“周期”: “开始”: “2019-04-08T12:21:39.1525361 + 03:00”, “结束”: “2019-04-09T11:21:39.1535328 + 03:00”, “值” :42
更新
使用匿名对象可以简化WriteJson
中的代码:
public override void WriteJson(JsonWriter writer, Period period, JsonSerializer serializer)
var token = JToken.FromObject(new Start = period.Start, End = period.End);
token.WriteTo(writer);
解决方案是使用Period
的子集:
// your external dependency
public class Period
public DateTime Start get; set;
public DateTime End get; set;
public int Count get; set;
public string Foo get; set;
// your copycat with only the properties you really need
public class Periodic
public DateTime Start get; set;
public DateTime End get; set;
public class Tempo
public Periodic Period get; set;
public int Value get; set;
public static void Main()
var period = new PeriodCount = 1, Foo = "bar", Start = DateTime.Now, End = DateTime.Now.AddDays(1);
var tempo = new TempoValue = 1, Period = new Periodic Start = period.Start, End = period.End ;
Console.WriteLine(JsonConvert.SerializeObject(tempo));
您还可以使用像Automapper这样的库来处理外部类和模仿者之间的映射。对于两个属性,它可能有点矫枉过正。
以上是关于如何在序列化期间忽略我不拥有的子类的属性?的主要内容,如果未能解决你的问题,请参考以下文章
在使用 Jackson 反序列化期间选择性地忽略 JSON 属性
在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性