json.net: указать конвертер для ключей словаря

У меня есть JSON:

{ "data": { "A": 5, "B": 6 }, "foo": "foo", "bar": "bar" } 

Мне нужно десериализовать данные в class:

 public Dictionary Data { get; set; } public string Foo { get; set; } public string Bar { get; set; } 

Но значения MyEnum – это CodeA и CodeB а не просто A и B соответственно.

У меня есть собственный конвертер, который может обрабатывать преобразование. Но как я могу указать JsonConverter для использования с ключами словаря?

Я считаю, что единственный способ – сделать JsonConverter для всего Dictionary или Dictionary .

Словарные ключи не считаются значениями и не будут запускаться через JsonConverters. TypeConverters были бы решением, но строка по умолчанию для преобразования enums будет введена до того, как она посмотрит на TypeConverters.

Итак … Я не думаю, что это можно сделать по-другому.

РЕДАКТИРОВАТЬ:

Не полностью протестирован, но я использую что-то вроде этого в моем проекте:

 public class DictionaryWithSpecialEnumKeyConverter : JsonConverter { public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotSupportedException(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; var valueType = objectType.GetGenericArguments()[1]; var intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), valueType); var intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType); serializer.Populate(reader, intermediateDictionary); var finalDictionary = (IDictionary)Activator.CreateInstance(objectType); foreach (DictionaryEntry pair in intermediateDictionary) finalDictionary.Add(Enum.Parse(MyEnum, "Code" + pair.Key, false), pair.Value); return finalDictionary; } public override bool CanConvert(Type objectType) { return objectType.IsA(typeof(IDictionary<,>)) && objectType.GetGenericArguments()[0].IsA(); } } 

Вам понадобится этот маленький помощник:

  public static bool IsA(this Type type, Type typeToBe) { if (!typeToBe.IsGenericTypeDefinition) return typeToBe.IsAssignableFrom(type); var toCheckTypes = new List { type }; if (typeToBe.IsInterface) toCheckTypes.AddRange(type.GetInterfaces()); var basedOn = type; while (basedOn.BaseType != null) { toCheckTypes.Add(basedOn.BaseType); basedOn = basedOn.BaseType; } return toCheckTypes.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeToBe); } 

Надеюсь, что это работает для вас.

Вот общее решение проблемы использования json с Dictionary с любым типом ключа:

 [JsonObject] public class MyKeyValuePair { public TKey MyKey; public TValue MyValue; [JsonConstructor] public MyKeyValuePair() { } public MyKeyValuePair(TKey t1, TValue t2) { MyKey = t1; MyValue = t2; } } [JsonObject] public class MyDictionaty { public ICollection> Collection; [JsonConstructor] public MyDictionaty() { } public MyDictionaty(Dictionary refund) { Collection = BuildMyKeyValuePairCollection(refund); } internal Dictionary ToDictionary() { return Collection.ToDictionary(pair => pair.MyKey, pair => pair.MyValue); } private ICollection> BuildMyKeyValuePairCollection(Dictionary refund) { return refund.Select(o => new MyKeyValuePair(o.Key, o.Value)).ToList(); } } [JsonObject] public class ClassWithDictionary { [JsonProperty] private readonly MyDictionary _myDictionary; private Dictionary _dic; [JsonConstructor] public ClassWithDictionary() { } public ClassWithDictionary(Dictionary dic) { _dic= dic; _myDictionary = new MyDictionaty(dic); } public Dictionary GetTheDictionary() { _dic = _dic??_myDictionary.ToDictionary(); return _dic; } } 
  • Порядок сериализованных полей с использованием JSON.NET
  • Может ли Json.NET сериализовать / десериализовать в / из streamа?
  • Сериализация нулевого значения в JSON.NET
  • Как сообщить Json.Net глобально применить StringEnumConverter ко всем enumsм
  • Линейная сериализация и де-сериализация
  • Удаление десериализации JSON в объект с помощью Json.NET
  • JsonValueProviderFactory выбрасывает «запрос слишком большой»
  • Как десериализовать данные JSON?
  • JSON.NET: зачем использовать JToken - когда-либо?
  • Отключить использование JSON.net
  • Хранить корпус при сериализации словарей
  • Interesting Posts

    Замена NA с последним значением, отличным от NA

    Как отключить определенные вкладки в Chrome?

    Найти элементы в одном столбце Excel, которые не находятся в другом столбце, и поместить их в новый столбец

    Хороший инструмент для поиска дубликатов фотографий на основе данных изображения

    Что означает «i» в селекторе атрибутов CSS?

    Чтение UTF-8 – маркер спецификации

    Добавить значение с плавающей запятой в ресурсы и значения Android

    Диспетчер задач показывает высокий процессор, но «пользователь» показывает по-разному

    Значение глобальной переменной сбрасывается после ее инициализации в ValueEventListener

    Как использовать литералы целочисленного числа при использовании общих типов?

    Принудительное обновление приложения для Android, когда доступна новая версия

    Эквивалентный код CreateObject в C #

    Создание ссылок, заключенных в квадратные скобки, а не цитаты

    Windows 8: Как закрыть (не спать) ноутбук на крышке близко?

    Лучший способ создать уникальный токен в Rails?

    Давайте будем гением компьютера.