2

小提琴测试:https ://dotnetfiddle.net/RyxMjm

using NewtonSoft.Json;

让我们SomeClass成为一个需要自定义 json 转换器的库类。它提供的库提供了自定义的 json 转换器,UsualConverter并通过在类定义中使用JsonConverter属性指定转换器将转换器链接到类。

    [JsonConverter(typeof(UsualConverter))]
    class SomeClass {
        public int A;
    }

    class UsualConverter : JsonConverter {
        public override bool CanConvert(Type objectType)
            => objectType == typeof(SomeClass);

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
            var jObject = JObject.ReadFrom(reader);
            return new SomeClass {
                A = jObject["A"].ToObject<int>(),
            };
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
            var jObject = new JObject();
            jObject["A"] = ((SomeClass)value).A;
            jObject.WriteTo(writer);
        }
    }

但是我现在需要为它实现和使用不同的 json 转换器。所以我创建了自己的:

    class SpecialConverter : JsonConverter {
        public override bool CanConvert(Type objectType)
            => objectType == typeof(SomeClass);

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
            var jObject = JObject.ReadFrom(reader);
            return new SomeClass {
                A = 100,
            };
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
            var jObject = new JObject();
            jObject["A"] = "SpecialValue";
            jObject.WriteTo(writer);
        }
    }

当我根本无法让 JsonConvert 使用我的新转换器时,就会出现问题......它总是使用在类定义中使用属性指定的原始标头。

以下代码引发异常。如何使用新的自定义转换器完成序列化/反序列化?

    class Program {
        static void Main(string[] args) {
            var settings = new JsonSerializerSettings();
            settings.Converters.Add(new SpecialConverter());
            var json = JsonConvert.SerializeObject(new SomeClass { A = 10 }, settings);
            if (!json.Contains("SpecialValue"))
                throw new Exception("Wrong converter was used.");
        }
    }

我可以编辑包含“违规”类的库,但是,我不想破坏已经使用该库的其他应用程序。如果涉及修改库代码的答案不会破坏已经使用该库的其他应用程序,则将被接受。

小提琴测试:https ://dotnetfiddle.net/RyxMjm

更新

使用我从重复问题的答案中学到的知识,我创建了以下扩展方法,以允许应用程序代码快速将备用 JsonConverter 应用于其序列化程序。它只能在应用程序代码已经将另一个应用程序代码应用于ContractResolver序列化程序设置对象的极少数情况下破坏应用程序代码。

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SomeNameSpace {

    public static class SerializerSettingsExtensions {

        public static void UseAlternateConverterForSomeClass(this JsonSerializerSettings settings, JsonConverter jsonConverter) {
            settings.ContractResolver = ConverterDisablingContractResolver.Instance;
            settings.Converters.Add(jsonConverter);
        }

        private class ConverterDisablingContractResolver : DefaultContractResolver {
            public static readonly ConverterDisablingContractResolver Instance = new ConverterDisablingContractResolver();
            private ConverterDisablingContractResolver() { }
            protected override JsonConverter ResolveContractConverter(Type objectType) {
                if (objectType == typeof(SomeClass)) return null;
                return base.ResolveContractConverter(objectType);
            }
        }
    }
}
4

0 回答 0