Использование [XmlAnyElement] - PullRequest
       0

Использование [XmlAnyElement]

2 голосов
/ 15 декабря 2011

Я пытаюсь сохранить данные в двух разных версиях объекта и не добиваюсь успеха.Может кто-нибудь сказать мне, что я делаю не так?

Версия 1 класса:

 [DataContract (Name="Person")]
 public class Person_V1
 {
     [DataMember(Name = "Name")]
     public string Name;

     [DataMember(Name = "Age")]
     public int Age;

     [XmlAnyElement]
     public XmlElement[] XElements;
}

Версия 2 класса:

[DataContract(Name = "Person")]
public class Person_V2
{
    [DataMember(Name = "Name")]
    public string Name;

    [DataMember(Name = "Age")]
    public int Age;

    [DataMember(Name = "Weight")]
    public int Weight;

    [XmlAnyElement]
    public XmlElement[] XElements;
}

Сохранение V2object:

private void btnSave_V2_Click(object sender, EventArgs e)
{
    Person_V2 p = new Person_V2() { Name = "Carrie", Age = 31, Weight = 125 };

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

    XmlWriterSettings settings = new XmlWriterSettings() { Indent = true };

    using (XmlWriter w = XmlWriter.Create("person.xml", settings))
        ds.WriteObject(w, p);
}

Восстановление V2 объекта в объект V1.Ожидается, что информация о переменной веса будет сохранена в массиве XElements, но этого не произойдет

private void btnRestore_V1_Click(object sender, EventArgs e)
{
    Person_V1 p;

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

    XmlReaderSettings settings = new XmlReaderSettings();

    using (XmlReader r = XmlReader.Create("person.xml", settings))
        p = (Person_V1)ds.ReadObject(r);

    MessageBox.Show(p.Name + " " + p.Age);
}

Ответы [ 3 ]

1 голос
/ 10 ноября 2013

Чтобы сохранить неизвестные элементы будущих или прошлых версий DataContract s, вы можете реализовать интерфейс IExtensibleDataObject.Это приведет к тому, что любые неизвестные элементы будут помещены в свойство с именем ExtensionData, которое позволяет в будущем повторную сериализацию без пропущенных данных.

Пример использования может быть следующим:

[DataContract(Name="Person")]
public class Person_V1 : IExtensibleDataObject
{
    [DataMember(Name = "Name")]
    public string Name;

    [DataMember(Name = "Age")]
    public int Age;

    public ExtensionDataObject ExtensionData { get; set; }
}

Когда *Объект 1011 * десериализуется в объект Person_V1, свойство Weight сохраняется в ExtensionData и возвращается в сериализованный поток при повторной сериализации.

1 голос
/ 15 декабря 2011

Классы Xml*Attribute используются XmlSerializer, а не DataContractSerializer.Насколько я знаю, DataContractSerializer не имеет никакого механизма для обработки этого сценария.Если вы можете, используйте XmlSerializer вместо этого, это гораздо более гибко.

0 голосов
/ 15 декабря 2011

Если это требование вашего приложения, вы можете добавить метод, украшенный атрибутом OnDeserializing , а затем реализовать собственную логику для добавления отсутствующих полей в коллекцию XmlElement.

...