Поделиться через


Образец сериализации слабо типизированных данных JSON

При сериализации пользовательского типа в заданный формат передачи или при десериализации формата передачи в пользовательский тип заданный пользовательский тип должен быть доступен как службе, так и клиенту. Обычно для этого к пользовательским типам применяется атрибут DataContractAttribute, а к их членам применяется атрибут DataMemberAttribute. Этот механизм также применим при работе с объектами JSON, как описано в разделе Как сериализовать и десериализовать данные JSON.

В некоторых сценариях службе или клиенту Windows Communication Foundation (WCF) требуется обращаться к объектам JSON, созданным службой или клиентом, которыми разработчик не может управлять. Чем большее число веб-служб публично предоставляют интерфейсы API в формате JSON, тем менее практично для разработчика WCF создавать локальные пользовательские типы, в которые будут десериализовываться произвольные объекты JSON. В этом образце описан механизм, позволяющий разработчикам WCF работать с произвольными десериализованными объектами JSON без создания пользовательских типов. Он называется слабо типизированной сериализацией объектов JSON, поскольку тип, в который десериализуется объект JSON, во время компиляции неизвестен.

Bb943471.note(ru-ru,VS.100).gifПримечание
Процедура настройки и инструкции по построению для этого образца приведены в конце этого раздела.

Например, API общедоступной веб-службы возвращает следующий объект JSON, который содержит определенные сведения о пользователе службы.

{"personal": {"name": "Paul", "age": 23, "height": 1.7, "isSingle": true, "luckyNumbers": [5,17,21]}, "favoriteBands": ["Band ABC", "Band XYZ"]}

Чтобы десериализовать этот объект, клиент WCF должен реализовать следующие пользовательские типы.

   [DataContract]
    public class MemberProfile
    {
        [DataMember]
        public PersonalInfo personal;

        [DataMember]
        public string[] favoriteBands;
    }

    [DataContract]
    public class PersonalInfo
    {
        [DataMember]
        public string name;

        [DataMember]
        public int age;

        [DataMember]
        public double height;

        [DataMember]
        public bool isSingle;

        [DataMember]
        public int[] luckyNumbers;
    }

Эта задача может быть громоздкой, особенно если клиент должен обрабатывать более одного типа объектов JSON.

Предоставляемый в этом образце тип JsonObject содержит слабо типизированное представление объекта JSON. JsonObject использует естественное сопоставление между объектами JSON и словарями .NET Framework и сопоставление между массивами JSON и массивами .NET Framework. В следующем примере кода демонстрируется тип JsonObject.

// Instantiation of JsonObject json omitted

string name = json["root"]["personal"]["name"];
int age = json["root"]["personal"]["age"];
double height = json["root"]["personal"]["height"];
bool isSingle = json["root"]["personal"]["isSingle"];
int[] luckyNumbers = {
                                     json["root"]["personal"]["luckyNumbers"][0],
                                     json["root"]["personal"]["luckyNumbers"][1],
                                     json["root"]["personal"]["luckyNumbers"][2] 
                                 };
string[] favoriteBands = {
                                        json["root"]["favoriteBands"][0],
                                        json["root"]["favoriteBands"][1]
                                    };

Обратите внимание что объекты и массивы JSON можно просматривать без необходимости объявлять их тип во время компиляции. Описание требования к объекту верхнего уровня ["root"] см. в разделе Сопоставление JSON и XML.

Bb943471.note(ru-ru,VS.100).gifПримечание
Класс JsonObject предоставлен исключительно в качестве примера. Он не был тщательно протестирован, и его не следует использовать в рабочей среде. Очевидным недостатком слабо типизированной сериализации JSON является плохая типобезопасность при работе с JsonObject.

Чтобы использовать тип JsonObject, контракт операции клиента должен использовать в качестве возвращаемого типа Message.

[ServiceContract]
    interface IClientSideProfileService
    {
        // There is no need to write a DataContract for the complex type returned by the service.
        // The client will use a JsonObject to browse the JSON in the received message.

        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        Message GetMemberProfile();
    }

Объект JsonObject создается, как показано в следующем коде.

// Code to instantiate IClientSideProfileService channel omitted…

// Make a request to the service and obtain the Json response
XmlDictionaryReader reader = channel.GetMemberProfile().GetReaderAtBodyContents();

// Go through the Json as though it is a dictionary. There is no need to map it to a .NET CLR type.
JsonObject json = new JsonObject(reader);

Конструктор JsonObject принимает объект XmlDictionaryReader, который получается через метод GetReaderAtBodyContents. Объект чтения содержит XML-представление сообщения JSON, полученного клиентом. Дополнительные сведения см. в разделе см. в разделе Сопоставление JSON и XML.

Программа выдает следующие результаты.

Service listening at https://localhost:8000/.
To view the JSON output from the sample, navigate to https://localhost:8000/GetMemberProfile
This is Paul's page. I am 23 years old and I am 1.7 meters tall.
I am single.
My lucky numbers are 5, 17, and 21.
My favorite bands are Band ABC and Band XYZ.

Настройка, построение и выполнение образца

  1. Убедитесь, что выполнены процедуры, описанные в разделе Процедура однократной настройки образцов Windows Communication Foundation.

  2. Выполните построение решения WeaklyTypedJson.sln, как описано в разделе Построение образцов Windows Communication Foundation.

  3. Запустите решение.

Bb943471.Important(ru-ru,VS.100).gif Примечание
Образцы уже могут быть установлены на компьютере. Перед продолжением проверьте следующий каталог (по умолчанию).

<диск_установки>:\WF_WCF_Samples

Если этот каталог не существует, перейдите на страницу Образцы Windows Communication Foundation (WCF) и Windows Workflow Foundation (WF) для .NET Framework 4, чтобы загрузить все образцы Windows Communication Foundation (WCF) и WF. Этот образец расположен в следующем каталоге.

<диск_установки>:\WF_WCF_Samples\WCF\Scenario\Ajax\WeaklyTypedJson