Виртуальные свойства дублируются во время сериализации при использовании атрибута XmlElement - PullRequest
1 голос
/ 20 апреля 2010

Цель:

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

Попытка:

После изучения IXmlSerializable и IXmlSerializable с помощью жутких методов XmlSchemaProvider и отражения voodoo для возврата специализированных схем и XmlQualifiedName в течение нескольких дней я обнаружил, что могу использовать простой атрибут [XmlElement] для достижения цели ... почти.

Проблема:

Переопределенные свойства появляются дважды при сериализации. Исключение гласит: «Элемент XML 'overriddenProperty' из пространства имен '' уже присутствует в текущей области. Используйте атрибуты XML, чтобы указать другое имя XML или пространство имен для элемента". Я попытался использовать * указанное свойство (см. Код), но оно не сработало.

Пример кода:

Class Declaration

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

[XmlInclude(typeof(DerivedClass))]
public class BaseClass
{
    public BaseClass() { }

    [XmlAttribute("virt")]
    public virtual string Virtual
    {
        get;
        set;
    }
    [XmlIgnore]
    public bool VirtualSpecified
    {
        get { return (this is BaseClass); }
        set { }
    }

    [XmlElement(ElementName = "B", Type = typeof(BaseClass), IsNullable = false)]
    [XmlElement(ElementName = "D", Type = typeof(DerivedClass), IsNullable = false)]
    public List<BaseClass> Children
    {
        get;
        set;
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass() { }

    [XmlAttribute("virt")]
    public override string Virtual
    {
        get { return "always return spackle"; }
        set { }
    }
}

Driver:

BaseClass baseClass = new BaseClass() { 
    Children = new List<BaseClass>()
};
BaseClass baseClass2 = new BaseClass(){};
DerivedClass derivedClass1 = new DerivedClass() { 
    Children = new List<BaseClass>()
};
DerivedClass derivedClass2 = new DerivedClass()
{
    Children = new List<BaseClass>()
};

baseClass.Children.Add(derivedClass1);
baseClass.Children.Add(derivedClass2);
derivedClass1.Children.Add(baseClass2);

Я боролся с этим в течение нескольких недель и не могу найти ответ нигде.

1 Ответ

2 голосов
/ 20 апреля 2010

Найден.

Решение:

Украсьте переопределенные свойства атрибутом [XmlIgnore].Правильное виртуальное значение все еще сериализуется.

Объявление класса

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

[XmlInclude(typeof(DerivedClass))]
public class BaseClass
{
    public BaseClass() { }

    [XmlAttribute("virt")]
    public virtual string Virtual
    {
        get;
        set;
    }

    [XmlElement(ElementName = "B", Type = typeof(BaseClass), IsNullable = false)]
    [XmlElement(ElementName = "D", Type = typeof(DerivedClass), IsNullable = false)]
    public List<BaseClass> Children
    {
        get;
        set;
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass() { }

    [XmlAttribute("virt")]
    [XmlIgnore]
    public override string Virtual
    {
        get { return "always return spackle"; }
        set { }
    }
}
...