Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базовые технологии платформы .NET.docx
Скачиваний:
15
Добавлен:
02.11.2018
Размер:
626.37 Кб
Скачать

Сериализация контрактов данных

Контракт данных – это тип (класс или структура), описывающий информационный фрагмент. Если в качестве контракта данных используется обычный класс, информационный фрагмент образуют открытые поля и свойства. Можно пометить тип атрибутом [DataContract]. Тогда информационный фрагмент будут составлять поля и свойства, помеченные атрибутом [DataMember]1. Видимость элементов при этом роли не играет.

[DataContract]

public class Student

{

[DataMember]

public string Name { get; set; }

[DataMember]

public int Age { get; set; }

[DataMember]

public double GPA { get; set; }

}

Атрибут [DataContract] имеет свойства Name и Namespace для указания имени и пространства имён корневого XML-элемента. У атрибута [DataMember] есть свойство Name, а также свойства Order (порядок сериализации членов контракта), IsRequired (обязательный элемент в сериализованном потоке), EmitDefaultValue (запись в поток значений элемента по умолчанию).

Если контракт будет десериализоваться в объекты потомков своего типа, эти типы должны быть упомянуты при помощи атрибута [KnownType]2.

[DataContract]

[KnownType(typeof(Postgraduate))]

public class Student { . . . }

public class Postgraduate : Student { . . . }

Если контракт является коллекцией объектов (как класс Group), он маркируется атрибутом [CollectionDataContract]. Кроме этого, для методов контракта данных применимы атрибуты [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized].

Для сериализации контракта данных используются классы:

  • DataContractSerializer ‑ сериализует контракт;

  • NetDataContractSerializer ‑ сериализует данные и тип контракта;

  • DataContractJsonSerializer ‑ сериализует контракта в формате JSON.

Рассмотрим ряд примеров сериализации контрактов данных:

var student = new Student { Name = "Smirnov", Age = 18, GPA = 9 };

// конструктор DataContractSerializer требует типа контракта данных

var ds = new DataContractSerializer(typeof(Student));

// сериализация (по умолчанию используется формат XML)

using (Stream s = File.Create("studentDS.xml"))

{

ds.WriteObject(s, student);

}

// десериализация

using (Stream s = File.OpenRead("studentDS.xml"))

{

student = (Student)ds.ReadObject(s);

}

// сериализация и десериализация в двоичном формате

using (Stream bs = File.Create("studentDS.bin"))

{

using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter(bs))

{

ds.WriteObject(w, student);

}

}

using (Stream bs = File.OpenRead("studentDS.bin"))

{

using (XmlDictionaryReader r = XmlDictionaryReader.CreateBinaryReader(bs,

XmlDictionaryReaderQuotas.Max))

{

student = (Student)ds.ReadObject(r);

}

}

// сериализация в формате JSON

var jsonds = new DataContractJsonSerializer(typeof(Student));

using (Stream s = File.Create("student.json"))

{

jsonds.WriteObject(s, student);

}

// используя NetDataContractSerializer, тип указывать не нужно

var netds = new NetDataContractSerializer();

using (Stream s = File.Create("studentNDS.xml"))

{

netds.WriteObject(s, student);

}

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

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

public class Student

{

public string Name { get; set; }

public int Age { get; set; }

public double GPA { get; set; }

}

var student = new Student {Name = "Smirnov", Age = 18, GPA = 9};

// при создании XmlSerializer требуется указать сериализуемый тип

var serializer = new XmlSerializer(typeof(Student));

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

using (Stream stream = File.Create("student.xml"))

{

serializer.Serialize(stream, student);

}

// десериализация

using (Stream stream = File.OpenRead("student.xml"))

{

student = (Student) serializer.Deserialize(stream);

}

Настройка XML-сериализации может быть выполнена при помощи атрибутов. [XmlRoot] применяется к типу и задаёт корневой элемент в XML-файле. При помощи [XmlElement] настраивается имя и пространство имён XML-элемента. [XmlAttribute] используется, если член класса требуется сохранить в виде XML-атрибута. Поля и свойства, которые не должны сохраняться, помечаются атрибутом [XmlIgnore]. Если тип содержит коллекцию объектов, то настройка имени этой коллекции и имени отдельного элемента выполняется при помощи атрибутов [XmlArray] и [XmlArrayItem].

public class Student

{

[XmlAttribute("name")]

public string Name { get; set; }

[XmlAttribute("age")]

public int Age { get; set; }

[XmlIgnore]

public double GPA { get; set; }

}

[XmlRoot("students")]

public class Group

{

public Student BestStudent { get; set; }

[XmlArray("list")]

[XmlArrayItem("student")]

public List<Student> List { get; set; }

}

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