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


сериализация XML

Сериализация — это процесс преобразования объекта в форму, которую можно легко транспортировать. Например, можно сериализовать объект и передать его через Интернет с помощью HTTP между клиентом и сервером. С другой стороны, десериализация восстанавливает объект из потока.

Сериализация XML сериализует только открытые поля и значения свойств объекта в XML-поток. Сериализация XML не включает сведения о типе. Например, если у вас есть объект Book , имеющийся в пространстве имен библиотеки , нет никаких гарантий, что он десериализирован в объект одного типа.

Замечание

Сериализация XML не преобразует методы, индексаторы, частные поля или свойства только для чтения (за исключением коллекций только для чтения). Чтобы сериализовать все поля и свойства объекта, как общедоступные, так и частные, используйте DataContractSerializer вместо сериализации XML.

Центральным классом в сериализации XML является класс XmlSerializer, а наиболее важными методами в этом классе являются методы Serialize и Deserialize. Компонент XmlSerializer создает файлы C#, компилирует их в файлы .dll, чтобы выполнить эту сериализацию. Средство генератора сериализатора XML (Sgen.exe) предназначено для создания этих сборок сериализации заранее для развертывания с помощью приложения и повышения производительности запуска. Поток XML, созданный XmlSerializer, соответствует рекомендациям Всемирного консорциума (W3C) по языку определения схемы XML (XSD) версии 1.0. Кроме того, созданные типы данных соответствуют документу с названием "Xml Schema Part 2: Datatypes".

Данные в объектах описываются с помощью конструкций языка программирования, таких как классы, поля, свойства, примитивные типы, массивы и даже внедренные XML в виде объектов XmlElement или XmlAttribute . Вы можете создавать собственные классы, аннотировать атрибутами или использовать средство определения схемы XML для создания классов на основе существующей схемы XML.

Если у вас есть XML-схема, можно запустить средство определения схемы XML для создания набора классов, строго типизированных в схему и аннотированных атрибутами. При сериализации экземпляра такого класса созданный XML-код соответствует схеме XML. Используя такой класс, вы можете программировать с легко управляемой объектной моделью, при этом гарантируя, что созданный XML-код соответствует XML-схеме. Это альтернатива использованию других классов в .NET, таких как классы XmlReader и XmlWriter , для анализа и записи XML-потока. Дополнительные сведения см. в xml-документах и данных. Эти классы позволяют анализировать любой XML-поток. В отличие от этого, используйте xmlSerializer , если xml-поток должен соответствовать известной схеме XML.

Атрибуты управляют потоком XML, созданным классом XmlSerializer , что позволяет задать пространство имен XML, имя элемента, имя атрибута и т. д. потока XML. Дополнительные сведения об этих атрибутах и способах управления сериализацией XML см. в разделе "Управление сериализацией XML с помощью атрибутов". Таблицу этих атрибутов, используемых для управления созданным XML-кодом, см. в разделе "Атрибуты, управляющие сериализацией XML".

Класс XmlSerializer может дополнительно сериализовать объект и создать закодированный XML-поток SOAP. Созданный XML соответствует разделу 5 документа консорциума World Wide Web Consortium с названием "Simple Object Access Protocol (SOAP) 1.1". Дополнительные сведения об этом процессе см. в статье "Практическое руководство. Сериализация объекта в виде потока XML SOAP-Encoded". См. таблицу атрибутов, которые управляют созданным XML, в разделе Атрибуты, которые управляют сериализацией SOAP в кодировке SOAP.

Класс XmlSerializer создает сообщения SOAP, созданные и передаваемые в веб-службы XML. Чтобы управлять сообщениями SOAP, можно применять атрибуты к классам, возвращаемым значениям, параметрам и полям, найденным в XML-файле веб-службы (ASMX). Вы можете использовать как атрибуты, перечисленные в разделах "Атрибуты, управляющие сериализацией XML", так и "Атрибуты, управляющие закодированной сериализацией SOAP", потому что XML веб-служба может использовать либо литеральный, либо закодированный стиль SOAP. Дополнительные сведения об использовании атрибутов для управления XML-веб-службой, созданной веб-службой XML, см. в статье о сериализации XML с помощью веб-служб XML. Дополнительные сведения о веб-службах SOAP и XML см. в разделе "Настройка форматирования сообщений SOAP".

Вопросы безопасности для приложений XmlSerializer

При создании приложения, использующего XmlSerializer, следует учитывать следующие элементы и их последствия:

  • XmlSerializer создает файлы C# (.cs) и компилирует их в .dll файлы в каталоге с именем переменной среды TEMP; сериализация происходит с этими библиотеками DLL.

    Замечание

    Эти сборки сериализации можно создать заранее и подписать с помощью средства SGen.exe. Это не работает на сервере веб-служб. Другими словами, он предназначен только для использования клиентом и для ручной сериализации.

    Код и библиотеки DLL уязвимы для вредоносного процесса во время создания и компиляции. Возможно, для двух или нескольких пользователей можно предоставить общий доступ к каталогу TEMP. Общий доступ к каталогу TEMP является опасным, если две учетные записи имеют разные привилегии безопасности, а учетная запись с более высоким уровнем привилегий запускает приложение с помощью XmlSerializer. В этом случае один пользователь может нарушить безопасность компьютера, заменив .cs или .dll файл, скомпилированный. Чтобы устранить эту проблему, всегда убедитесь, что каждая учетная запись на компьютере имеет свой собственный профиль. По умолчанию переменная среды TEMP указывает на другой каталог для каждой учетной записи.

  • Если злоумышленник отправляет непрерывный поток XML-данных на веб-сервер (атака типа "отказ в обслуживании"), XmlSerializer продолжает обрабатывать данные, пока компьютер не исчерпает ресурсы.

    Эта атака устранена, если вы используете компьютер под управлением служб IIS, а приложение работает в службах IIS. СЛУЖБА IIS включает шлюз, который не обрабатывает потоки дольше заданного объема (по умолчанию — 4 КБ). Если вы создаете приложение, которое не использует службы IIS и десериализируется с xmlSerializer, следует реализовать аналогичный шлюз, который предотвращает атаку типа "отказ в обслуживании".

  • XmlSerializer сериализует данные и запускает любой код, используя любой тип, предоставленный ему.

    Существует два способа, в которых вредоносный объект представляет угрозу. Он может запустить вредоносный код или внедрить вредоносный код в файл C#, созданный xmlSerializer. Во втором случае существует теоретическая вероятность того, что вредоносный объект может каким-то образом внедрить код в файл C#, созданный XmlSerializer. Хотя эта проблема тщательно рассмотрена, и такая атака считается маловероятной, следует принять меры предосторожности, чтобы никогда не сериализовать данные с неизвестным и ненадежным типом.

  • Сериализованные конфиденциальные данные могут быть уязвимыми.

    После сериализации данных XmlSerializer его можно сохранить в виде XML-файла или другого хранилища данных. Если хранилище данных доступно другим процессам или отображается в интрасети или в Интернете, данные могут быть украдены и использованы вредоносным образом. Например, если вы создаете приложение, которое сериализует заказы, содержащие номера кредитных карт, данные очень чувствительны. Чтобы предотвратить это, всегда защитите хранилище данных и выполните действия, чтобы сохранить его в закрытом режиме.

Сериализация простого класса

В следующем примере кода показан базовый класс с открытым полем.

Public Class OrderForm
    Public OrderDate As DateTime
End Class
public class OrderForm
{
    public DateTime OrderDate;
}

При сериализации экземпляра этого класса он может принимать следующий вид.

<OrderForm>
    <OrderDate>12/12/01</OrderDate>
</OrderForm>

Дополнительные примеры сериализации см. в примерах сериализации XML.

Элементы, которые можно сериализовать

Следующие элементы можно сериализовать с помощью класса XmlSerializer :

  • Общедоступные свойства чтения и записи и поля открытых классов.

  • Классы, реализующие ICollection или IEnumerable.

    Замечание

    Сериализуются только коллекции, а не общедоступные свойства.

  • Объекты XmlElement.

  • Объекты XmlNode.

  • Объекты DataSet.

Дополнительные сведения о сериализации или десериализации объектов см. в статье "Практическое руководство. Сериализация объекта и практическое руководство. Десериализация объекта".

Преимущества использования сериализации XML

Класс XmlSerializer предоставляет полный и гибкий элемент управления при сериализации объекта в формате XML. При создании веб-службы XML можно применить атрибуты, управляющие сериализацией к классам и членам, чтобы обеспечить соответствие выходных данных XML определенной схеме.

Например, XmlSerializer позволяет:

  • Укажите, должно ли поле или свойство быть закодировано как атрибут или элемент.

  • Укажите используемое пространство имен XML.

  • Укажите имя элемента или атрибута, если поле или имя свойства недопустимо.

Еще одним преимуществом сериализации XML является отсутствие ограничений на разрабатываемые приложения, если созданный XML-поток соответствует заданной схеме. Представьте схему, используемую для описания книг. Он содержит заголовок, автор, издатель и номер ISBN. Вы можете разрабатывать приложение, обрабатывающее XML-данные любым способом, например в виде заказа книги или в качестве инвентаризации книг. В любом случае единственное требование заключается в том, что XML-поток соответствует указанной схеме языка определения схемы XML (XSD).

Аспекты сериализации XML

При использовании класса XmlSerializer следует учитывать следующее:

  • Средство Sgen.exe специально разработано для создания сборок сериализации для оптимальной производительности.

  • Сериализованные данные содержат только сами данные и структуру классов. Информация об идентификаторах типов и сборках отсутствует.

  • Сериализуются только общедоступные свойства и поля. Свойства должны иметь общедоступные методы доступа (методы get и set). Если необходимо сериализовать не открытые данные, используйте DataContractSerializer класс, а не сериализацию XML.

  • Класс должен иметь конструктор без параметров, чтобы сериализоваться с помощью XmlSerializer.

  • Методы нельзя сериализовать.

  • XmlSerializer может обрабатывать классы, реализующие IEnumerable или ICollection по-разному, если они соответствуют определенным требованиям, как показано ниже.

    Класс, реализующий IEnumerable , должен реализовать открытый метод Add , который принимает один параметр. Параметр метода Add должен быть согласованным (полиморфным) с типом, возвращаемым из свойства IEnumerator.Current , возвращаемого из метода GetEnumerator .

    Класс, реализующий ICollection в дополнение к IEnumerable (например , CollectionBase), должен иметь открытое свойство индексированного элемента (индексатор в C#), которое принимает целое число, и оно должно иметь открытое свойство Count целого числа типа. Параметр, переданный методу Add , должен иметь тот же тип, что и возвращаемый из свойства Item , или один из баз этого типа.

    Для классов, реализующих ICollection, сериализуемые значения извлекаются из индексированного свойства Item , а не путем вызова GetEnumerator. Кроме того, открытые поля и свойства не сериализуются, за исключением открытых полей, возвращающих другой класс коллекции (который реализует ICollection). Примеры сериализации XML.

Сопоставление типов данных XSD

Документ W3C с названием XML Schema Part 2: Datatypes указывает простые типы данных, разрешенные в схеме языка определения схемы XML (XSD). Для многих из них (например, int и decimal) существует соответствующий тип данных в .NET. Однако некоторые типы данных XML не имеют соответствующего типа данных .NET, например типа данных NMTOKEN . В таких случаях при использовании средства определения схемы XML (инструмент определения схемы XML (Xsd.exe)) для создания классов из схемы соответствующий атрибут применяется к элементу строки типа, а его свойство DataType имеет имя типа XML. Например, если схема содержит элемент с именем MyToken с типом ДАННЫХ XML NMTOKEN, созданный класс может содержать элемент, как показано в следующем примере.

<XmlElement(DataType:="NMTOKEN")> _
Public MyToken As String
[XmlElement(DataType = "NMTOKEN")]
public string MyToken;

Аналогичным образом, если вы создаете класс, который должен соответствовать определенной схеме XML (XSD), необходимо применить соответствующий атрибут и задать его свойство DataType в нужное имя типа данных XML.

Полный список сопоставлений типов см. в свойстве DataType для любого из следующих классов атрибутов:

См. также