8

什么时候using Newtonsoft.Json,我可以通过将转换器添加到顶层SerializerSettings或将其提供给转换调用来完成我需要的工作 - 一切都运行良好。

我希望提取我的一些全局转换器,以便在实际需要转换的相关位置以声明方式应用。

我知道以下技术:-

  • 类型级别[JsonConverter(typeof(Converters.StringEnumConverter))]直接在类型上X
  • 成员级别[JsonConverter(typeof(Converters.StringEnumConverter))],如果成员属于类型X
  • 项目级别[JsonProperty(ItemConverterType=typeof(Converters.StringEnumConverter)],如果成员实际上是一个数组等X

我遇到的问题是我使用的一些全局转换器在嵌套类型上运行,例如,如果我有 type 的成员Tuple<X[],Nullable<X>>,我无法表达“如果在处理此字段或任何子字段时遇到 X它,做转换”语义,而不是得到一个Newtonsoft.Json.JsonSerializationException.

这种“对于这棵树,也请使用这个转换器”机制是否存在?我想避免必须为我想要转换的任何东西定义一个顶级类型,然后用 标记该类型JsonConverter来解决这个问题?

4

1 回答 1

1

如果我理解正确并根据官方文档,您可以直接应用转换器并使用自定义转换器按类型过滤:

SomeType someObject = new SomeType();
string json = JsonConvert.SerializeObject(someObject, Formatting.Indented, new MyCustomConverter(typeof(SomeType)));

public class MyCustomConverter : JsonConverter
{

     private readonly Type[] _types;

     public MyCustomConverter (params Type[] types)
     {
         _types = types;
     }

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
         JToken t = JToken.FromObject(value);

         if (t.Type != JTokenType.Object)
         {
             t.WriteTo(writer);
         }
         else
         {
             JObject o = (JObject)t;
             IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();

             o.AddFirst(new JProperty("Keys", new JArray(propertyNames)));

             o.WriteTo(writer);
        }
     }

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

     public override bool CanRead
     {
          get { return false; }
     }

     public override bool CanConvert(Type objectType)
     {
          return _types.Any(t => t == objectType);
     }
}

来源:https ://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm

于 2018-09-11T11:49:33.907 回答