• 定制json序列化


    最近有人问我怎么定制一个json序列化,使序列化的时候只写出声明的父类成员,而不要把实际子类的成员写出来。当然,序列化用的是大家用的最多的json.net。

    简单的说,这是个契约怎么解析的问题,json.net选择使用实际类型自然是有多方面的考量,毕竟申明类型可以是抽象类或接口等。废话不说了,直接上代码(仅用于示例,要用于生产的话需要处理各种边缘情况)。

    1. 类型关系

      public class RootObj
      {
          public A A { get; set; }
      }
      
      public class A
      {
          public string X { get; set; }
      }
      
      public class B : A
      {
          public string Y { get; set; }
      }
      
    2. 实例和序列化

      var r = new RootObj { A = new B { X = "x", Y = "y" } };
      Console.WriteLine(JsonConvert.SerializeObject(r));
      

      在什么都不改的情况下,输出是:

      {"A":{"Y":"y","X":"x"}}
      

      而期望值是:

      {"A":{"X":"x"}}
      

      我们期望只输出A的成员。

    3. 写自己的JsonConverter:

      public class JC<T> : JsonConverter
      {
          public override bool CanConvert(Type objectType) => throw new NotImplementedException();
      
          public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => throw new NotImplementedException();
      
          public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
          {
              writer.WriteStartObject();
              var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(typeof(T));
              foreach (var prop in contract.Properties)
              {
                  writer.WritePropertyName(prop.PropertyName);
                  serializer.Serialize(writer, prop.ValueProvider.GetValue(value));
              }
              writer.WriteEndObject();
          }
      }
      
    4. 标记我们的类型

      public class RootObj
      {
          [JsonConverter(typeof(JC<A>))]
          public A A { get; set; }
      }
      
    5. Run! 然后就可以发现结果和我们期待的一样了:)

    源代码传输门

  • 相关阅读:
    Bit,Byte,Word,Dword,Qword
    One good turn deserves another
    IHttpModule & IHttpHandler
    畅想:哈夫曼树的应用
    The Controls collection cannot be modified because the control contains code blocks
    Talk O/RM (DAL) too ...
    实现对象集合枚举接口
    [ZT]实现创造生命的古老梦想——合成生物学的发展走向
    笔记本基础知识篇之DVI接口详解
    Analysis Services: write back
  • 原文地址:https://www.cnblogs.com/vwxyzh/p/9377126.html
Copyright © 2020-2023  润新知