自定义序列化父项和嵌套项

时间:2019-03-19 13:26:44

标签: c# json json.net

我有一种情况,我想从JSON的一些多余项中删除数据。 (我不能仅仅标记不使用Newtonsoft编写的项目,因为我需要它们进行另一个序列化调用。)

我正在使用自定义序列化器来执行此操作,但是它没有为嵌套对象调用序列化器。也许采用JsonConverter数组的SerializeObject不是正确的调用。

这是完整的代码示例,其中从未调用CSerializer。

rq.fit.sfnc

编辑-基于Jesse解决方案的工作代码。

  public class PItem
  {
    public string name = "Parent";
    public CItem child = new CItem();
    public string type = "P";
  }

  public class CItem
  {
    public string name = "Child";
    public int prop = 100;
    public string[] codes = { "122a", "123b" };
  }

  class PSerializer : JsonConverter
  {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
      writer.Formatting = Formatting.Indented;
      PItem p = value as PItem;
      JObject jo = JObject.FromObject((PItem)value);

      jo.Remove("type");    

      jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
      throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
      return objectType == typeof(PItem);
    }
  }


  class CSerializer : JsonConverter
  {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
      writer.Formatting = Formatting.Indented;
      JObject jo = JObject.FromObject((CItem)value);

      jo.Remove("codes");
      jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
      throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
      return objectType == typeof(CItem);
    }
  }



  class JSONTest
  {

    public string TestConvert()
    {
      PItem p = new PItem();
      JsonConverter[] serializers = { new PSerializer(), new CSerializer() };
      return JsonConvert.SerializeObject(p, serializers);
    }
  }

1 个答案:

答案 0 :(得分:1)

使用自定义IContractResolver可能更容易做到这一点:

public class IgnoreTypeContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        if (property.DeclaringType == typeof(PItem) && property.PropertyName == "type")
        {
            property.ShouldSerialize = i => false;
            property.Ignored = true;
        }

        return property;
    }
}

用法:

var settings = new JsonSerializerSettings();
settings.ContractResolver = new IgnoreTypeContractResolver();
var json = JsonConvert.SerializeObject(pitem, settings);

编辑:如果您确实想使用JsonConverter,则必须自己编写PItem对象并使用JsonSerializer序列化子项:

// Inside your custom JsonConverter
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    var pitem = value as PItem;
    writer.WriteStartObject();
    writer.WritePropertyName("name");
    serializer.Serialize(writer, pitem.name);
    writer.WritePropertyName("child");

    // This respects any additional JsonConverters added to the serializer
    serializer.Serialize(writer, pitem.child);
    writer.WriteEndObject();
}