#c# #serialization #datacontractserializer
#c# #сериализация #datacontractserializer
Вопрос:
Как мне сериализовать и десериализовать несколько объектов с помощью DataContractSerializer? Сериализация проходит нормально, однако во время десериализации я получаю сообщение об ошибке
«Операция сериализации завершилась неудачно. Причина: произошла ошибка десериализации объекта сериализации типа.Человек. Существует несколько корневых элементов. «
В сообщении об ошибке четко указано, что в сериализованном документе отсутствует корневой элемент. Но как мне это преодолеть?
Вот код:
[DataContract]
class Person {
[DataMember(Name = "CustName")]
internal string Name;
public Person(string n) {Name = n;}
}
class Program {
public static void Main() {
WriteObject("d:\temp\DataContractExample.xml" , "Mary");
WriteObject("d:\temp\DataContractExample.xml", "Joe");
ReadObject("d:\temp\DataContractExample.xml");
}
public static void WriteObject(string path, string name) {
Person p1 = new Person(name);
FileStream fs = new FileStream(path, FileMode.Append);
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs);
DataContractSerializer ser = new DataContractSerializer(typeof(Person));
ser.WriteObject(writer, p1);
writer.Close();
fs.Close();
}
public static void ReadObject(string path) {
FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(Person));
// Deserialize the data and read it from the instance.
Person[] newPerson = (Person[])ser.ReadObject(reader);
Console.WriteLine("Reading this object:");
Console.WriteLine(String.Format("{0}", newPerson[0].Name));
fs.Close();
}
Когда я читаю из DataContractSerializer, ser.readObject(reader), я получаю исключение, о котором я упоминал выше.
Возможно ли создать корневой элемент при сохранении нескольких объектов с помощью DataContractSerializer?
Комментарии:
1. Однако, если формат хранилища можно изменить, обратите внимание, что некоторые форматы можно безопасно добавлять; дайте мне знать, если вас может заинтересовать аналогичный пример с использованием другого формата данных (но который работает)
2. Также обратите внимание — вы пишете (отдельно) два
Person
экземпляра и пытаетесь десериализоватьPerson[]
— но это имеет совсем другой макет3. Да, Марк! О каких других форматах хранения вы говорите. Мне помогут любые указатели. Я создаю решение для хранения данных для иерархии рабочего процесса. Поэтому мне нужно динамически добавлять, изменять и удалять элементы.
4. добавление выполняется легко; изменение и удаление из середины файла обычно означает перезапись всего файла
5. Примечание: если вы можете сериализовать a
List<Person>
в первую очередь, это может быть не проблема (т. Е. Она будет работать с DataContractSerializer)
Ответ №1:
DataContractSerializer
работает с XML-документами, поэтому ожидает один элемент верхнего уровня. Самым простым подходом было бы сериализовать a List<Person>
, что должно избежать этого. Вы также можете добавить внешний элемент вручную, возможно, используя XmlReader
и ReadSubtree
во время сериализации (хотя обратите внимание: это ужасно тяжелая работа).
Однако самый простой вариант — просто сериализовать a List<Person>
с самого начала и десериализовать как a List<Person>
— тогда это будет один XML-фрагмент, так что это не расстроит десериализатор.