【问题标题】:Getting Converters specified via Attributes to be equivalent to global ones in json.net让通过属性指定的转换器等效于 json.net 中的全局转换器
【发布时间】:2018-12-07 05:28:45
【问题描述】:

using Newtonsoft.Json 时,我可以通过将转换器添加到顶级SerializerSettings 或将其提供给转换调用来完成我需要的工作 - 一切正常。

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

我知道以下技巧:-

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

我遇到的问题是我使用的一些全局转换器在嵌套类型上运行,例如如果我有 Tuple<X[],Nullable<X>> 类型的成员,我无法表达 “如果您在处理此字段或其任何子字段时遇到 X,请进行转换” 语义,而不是获得 @987654330 @。

这样的“对于这棵树,也请使用这个转换器”机制存在吗?我想避免必须为我想要转换的任何内容定义顶级类型,然后使用 JsonConverter 标记该类型以解决此问题?

【问题讨论】:

    标签: .net json json.net converters jsonconverter


    【解决方案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

    【讨论】:

    • 您好,感谢您抽出宝贵的时间做出响应,并对响应缓慢感到抱歉 - 问题是,如果我正在序列化一个包含 B 的 A,该 B 需要字段 C 来应用转换器 D,我不能只通过 D - 我需要走动结构以确保我也不需要转换器 E,并且不会比将它们放入设置中更好。因此,要根据您的答案重申问题,难题是我如何让MyCustomConverter 在不被外部传递的情况下在 D 上工作。我可以在 B 或 C 上放置一个属性。不必传入代码或放在 A 上。
    • IOW 我有转换器,我有一个嵌套结构,如果我将它传递给 JsonConvert 或在设置中,它包含转换器工作的东西。如果我把它放在最里面的类型上,这正是需要的,它有时会起作用。但如果是Tuple&lt;T, U&gt;,我不能在上面放任何东西来让你转换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    相关资源
    最近更新 更多