Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Троелсен Э. Язык программирования С# 2010 и п...docx
Скачиваний:
113
Добавлен:
21.09.2019
Размер:
6.92 Mб
Скачать

Сериализация объектов с помощью SoapFormatter

Следующим вариантом является тип SoapFormatter. Тип SoapFormatter сохраняет объектный граф в сообщении SOAP (Simple Object Access Protocol – простой протокол доступа к объектам), что делает этот вариант форматирования прекрасным выбором при передаче объектов средствами удаленного взаимодействия по протоколу HTTP. Если вы не знакомы со спецификациями SOAP, не волнуйтесь. В сущности, SOAP определяет стандартный процесс, с помощью которого можно вызывать методы не зависящим от платформы и ОС способом (мы рассмотрим SOAP чуть более подробно в последней главе этой книги при обсуждении Web-сервисов XML).

В предположении о том, что вы установили ссылку на компоновочный блок System.Runtime.Serialization.Formatters.Soap.dll, можно реализовать сохранение и восстановление JamesBondCar в формате сообщения SOAP с помощью замены BinaryFormatter на SoapFormatter. Рассмотрите следующий программный код, который выполняет сериализацию объекта в локальный файл с именем CarData.soap.

using System.Runtime.Serialization.Formatters.Soap;

static void Main(string[] args) {

 …

 // Сохранение объекта в файл CarData.soap в формате SOAP.

 SoapFormatter soapFormat = new SoapFormatter();

 fStream = new FileStream("CarData.soap", FileMode.Create, FileAccess.Write, FileShare.None);

 soapFormat.Serialize(fStream, jbc);

 fStream.Close();

 Console.ReadLine();

}

Как и ранее, здесь просто используются Serialize() и Deserialize() для перемещения объектного графа в поток и восстановления его из потока. Если открыть полученный файл *.soap, вы увидите в нем элементы XML, представляющие значения JamesBondCar и взаимосвязи между объектами графа (с помощью лексем #ref). Рассмотрите следующий фрагмент XML-кода, соответствующий конечному результату (для краткости здесь опущены указания на пространства имен XML).

‹SOAP-ENV:Envelope xmlns:xsi="…"›

 ‹SOAP-ENV:Body›

  ‹a1:JamesBondCar id="ref-1" xmlns:a1="…"›

   ‹canFly›true‹/canFly›

   ‹canSubmerge›false‹/canSubmerge›

   ‹theRadio href="#ref-3"/›

   ‹isHatchBack›false‹/isHatchBack›

  ‹/a1:JamesBondCar›

  ‹a1:Radio id="ref-3" xmlns:a1="…"›

   ‹hasTweeters›true‹/hasTweeters›

   ‹hasSubWoofers›false‹/hasSubWoofers›

   ‹stationPresets href="ref-4"/›

  ‹/a1:Radio›

  ‹SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="xsd:dooble[3]"›

   ‹item›89.3‹/item›

   ‹item›105.1‹/item›

   ‹item›97.1‹/item›

  ‹/SOAP-ENC:Array›

 ‹/SOAP-ENV:Body›

 ‹/SOAP-ENV:Envelope›

Сериализация объектов с помощью XmlSerializer

Вдобавок к SOAP и двоичному формату, компоновочный блок System.Xml.dll предлагает третий формат, обеспечиваемый типом System.Xml.Serialization. XmlSerializer который может использоваться для сохранения состояния данного объекта в виде "чистого" XML в противоположность данным XML, упакованным в сообщении SOAP. Работа с этим типом немного отличается от работы с типами SoapFormatter и BinaryFormatter. Рассмотрим следующий программный код.

using Sуstem.Xml.Serialization;

static void Main(string[] args) {

 …

 // Сохранение объекта в файл CarData.xml в формате XML.

 XmlSerializer xmlFormat = new XmlSerializer(typeof(JamesBondCar), new Type[] { typeof(Radio), typeof(Car) });

 fStream = new FileStream("CarData.xml", FileMode.Create, FileAccess.Write, FileShare.None);

 xmlFormat.Serialize(fStream, jbc);

 fStream.Close();

 …

}

Здесь главным отличием является то, что тип XmlSerializer требует указания информации о типе соответствующего элемента объектного графа. Обратите внимание на то, что первый аргумент конструктора XmlSerializer определяет корневой элемент XML-файла, а второй аргумент является массивом типов System.Type, содержащих метаданные подчиненных элементов. Если заглянуть в сгенерированный файл CarData.xml, вы увидите следующий XML-код (здесь он приводится в сокращенном виде).

‹?xml version="1.0" encoding="utf-8"?›

 ‹JamesBondCar xmlns:xsi="…"›

  ‹theRadio›

   ‹hasTweeters›true‹/hasTweeters›

   ‹hasSubWoofers›false‹/hasSubwoofers›

   ‹stationPresets›

    ‹double›89.3‹/double›

    ‹double›105.1‹/double›

    ‹double›97.1‹/double›

   ‹/stationPresets›

  ‹/theRadio›

  ‹isHatchBack›false‹/isHatchBack›

  ‹canFly›true‹/canFly›

  ‹canSubmerge›false‹/canSubmerge›

 ‹/JamesBondCar›

Замечание. Для XmlSerializer требуется, чтобы все типы в объектном графе, предназначенные для сериализации, поддерживали конструктор, заданный по умолчанию (так что не забудьте добавить его, если вы определили пользовательские конструкторы). Если это условие не будет выполнено, в среде выполнения будет сгенерировано исключение InvalidOperationException.