如何在序列化期间忽略我不拥有的子类的属性?

我有一个类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。


我尝试使用 aDefaultContractResolver但没有成功:


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();

    }

}

我尝试使用 aJsonConverter但没有成功:


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. 如何在序列化期间忽略我不拥有的子类的属性?


一只名叫tom的猫
浏览 102回答 3
3回答

当年话下

JsonConverter您可以为类创建强类型Period:public class PeriodConverter : JsonConverter<Period>{&nbsp; &nbsp; public override void WriteJson(JsonWriter writer, Period period, JsonSerializer serializer)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; writer.WriteStartObject();&nbsp; &nbsp; &nbsp; &nbsp; writer.WritePropertyName(nameof(Period.Start));&nbsp; &nbsp; &nbsp; &nbsp; writer.WriteValue(period.Start);&nbsp; &nbsp; &nbsp; &nbsp; writer.WritePropertyName(nameof(Period.End));&nbsp; &nbsp; &nbsp; &nbsp; writer.WriteValue(period.End);&nbsp; &nbsp; &nbsp; &nbsp; writer.WriteEndObject();&nbsp; &nbsp; }&nbsp; &nbsp; public override Period ReadJson(JsonReader reader, Type objectType, Period existingValue, bool hasExistingValue,&nbsp; &nbsp; &nbsp; &nbsp; JsonSerializer serializer)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; throw new NotSupportedException();&nbsp; &nbsp; }}用法:var tempo = new Tempo{&nbsp; &nbsp; Period = new Period&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Start = DateTime.Now.AddDays(-1),&nbsp; &nbsp; &nbsp; &nbsp; End = DateTime.Now.AddHours(-1),&nbsp; &nbsp; &nbsp; &nbsp; Count = 42,&nbsp; &nbsp; &nbsp; &nbsp; Foo = "Foo"&nbsp; &nbsp; },&nbsp; &nbsp; 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){&nbsp; &nbsp; var token = JToken.FromObject(new {Start = period.Start, End = period.End});&nbsp; &nbsp; token.WriteTo(writer);}

慕斯王

制作子类:public class Periodic{&nbsp; &nbsp; public DateTime Start { get; set; }&nbsp; &nbsp; public DateTime End { get; set; }}使用带有此代码的自定义转换器:public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer){&nbsp; &nbsp; Periodic periodic = (Periodic)value;&nbsp; &nbsp; JToken t = JToken.FromObject(periodic);&nbsp; &nbsp; t.WriteTo(writer);}

斯蒂芬大帝

一种解决方案是使用以下子集Period:// your external dependencypublic class Period{&nbsp; &nbsp; public DateTime Start { get; set; }&nbsp; &nbsp; public DateTime End { get; set; }&nbsp; &nbsp; public int Count { get; set; }&nbsp; &nbsp; public string Foo { get; set; }}// your copycat with only the properties you really needpublic class Periodic{&nbsp; &nbsp; public DateTime Start { get; set; }&nbsp; &nbsp; public DateTime End { get; set; }}public class Tempo{&nbsp; &nbsp; public Periodic Period { get; set; }&nbsp; &nbsp; public int Value { get; set; }}public static void Main(){&nbsp; &nbsp; var period = new Period{Count = 1, Foo = "bar", Start = DateTime.Now, End = DateTime.Now.AddDays(1)};&nbsp; &nbsp; var tempo = new Tempo{Value = 1, Period = new Periodic {Start = period.Start, End = period.End} };&nbsp; &nbsp; Console.WriteLine(JsonConvert.SerializeObject(tempo));}您还可以使用像Automapper这样的库来处理外部类和模仿者之间的映射。对于两个属性,它可能有点矫枉过正。
打开App,查看更多内容
随时随地看视频慕课网APP