Динамический выбор типа путем проверки входящего JSON в WCF?

#.net #wcf #web-services #json #serialization

#.net #wcf #веб-сервисы #json #сериализация

Вопрос:

У меня сложная иерархия объектов JSON, отправляемых в службу WCF. По дизайну и другим требованиям каждый объект JSON имеет целочисленный идентификатор, концептуально представляющий его тип или расположение полей (давайте назовем это идентификатором типа).

Чего я хотел бы достичь, так это контроля над тем, какой .Тип NET выбирается для десериализации каждого объекта JSON посредством проверки каждого входящего идентификатора целочисленного типа.

Пример ввода:

 {
 "typeId": 4,
 "someField1": "foo",
 "someField2": "bar",
 "otherObject": 
    {
     "typeId": 7
     "someField3": "abc",
     "someField4": "xyz"
    }
}
  

Примерный (идеальный) процесс:

 1. I receive partially parsed object.
2. I inspect "typeId" which has value 4.
3. I notify the deserialization process that I elect to use my .NET type FooBarA.
4. I receive partially parsed object.
5. I inspect "typeId" which has value 7.
6. I notify the deserialization process that I elect to use my .NET type FooBarB.
  

Возможно ли это или подобное? Кажется, я припоминаю, что службы в стиле asmx использовались для включения поля __type, аналогичного моему идентификатору типа, я полагаю, но я не помню его точное назначение или, возможно, это может быть включено в WCF в качестве альтернативы.

Ответ №1:

Вы можете собрать входящий JSON либо в виде строки (если вам нужен «конкретный» тип), либо вы можете принять JSON в виде потока (очень полезно, если вы работаете в сценарии, основанном на REST), а затем скопировать его в MemoryStream для многократной обработки. Поскольку DataContractJsonSerializer работает вне потока, ваш лучший вариант использования — выгрузить его в MemoryStream.

Описываемый вами вариант использования десериализации будет довольно сложным в реализации, потому что если вложенный объект (в вашем случае «otherObject») не является членом родительского класса (в данном случае FooBarA), то процесс десериализации просто проигнорирует значение, потому что ему некуда его поместить.

Переключение передач, более трудоемкий процесс будет использовать Json.Net и вы могли бы пошагово использовать JSON в том же стиле, что и при использовании Linq to XML. Преимущество Json.Суть в том, что это позволяет вам играть с JSON, который не обязательно идеально соответствует конкретным классам. Это не очень хорошо сочетается с WCF в цепочке сериализации, но я использовал это несколько раз на стороне WCF для обработки предоставляемого JSON, который не совсем соответствует тому, что ищет конкретный класс.

Вы можете найти Json.Сеть здесь — http://json.codeplex.com /

Комментарии:

1. В моем случае, если вложенный объект когда-либо мог быть частью родительского объекта, родительский целевой тип всегда будет иметь соответствующее поле строго типизированного типа.

2. В этом случае класс должен десериализоваться должным образом с помощью DataContractJsonSerializer по умолчанию для родительского типа без необходимости что-либо делать.

3. Похоже, что нет. Я думаю, потому что поле введено как базовый класс. Мне нужно иметь возможность проверять идентификатор типа, чтобы знать, какой производный класс использовать для десериализации. В любом случае, я разработал решение с использованием Json. СЕТЬ с перечитыванием и JsonConverter. Спасибо.