Предотвратить XmlSerializer от испускания xsi: type на унаследованных типах

Мне удалось сериализовать класс, который наследуется от базового класса к XML. Однако .NET XmlSerializer создает XML-элемент, который выглядит следующим образом:

<BaseType xsi:Type="DerivedType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Это, однако, заставляет приемную часть веб-службы задушить и создать ошибку, которая составляет: извините, мы не знаем "DerivedType".

Как я могу предотвратить использование XmlSerializer атрибута xsi: Type? Спасибо!

Ответы

Ответ 1

Вы можете использовать атрибут XmlType, чтобы указать другое значение для атрибута type:

[XmlType("foo")]
public class DerivedType {...}

//produces

<BaseType xsi:type="foo" ...>

Если вы действительно хотите полностью удалить атрибут type, вы можете написать свой собственный XmlTextWriter, который пропустит атрибут при записи (вдохновленный этой записью в блоге):

public class NoTypeAttributeXmlWriter : XmlTextWriter
{
    public NoTypeAttributeXmlWriter(TextWriter w) 
               : base(w) {}
    public NoTypeAttributeXmlWriter(Stream w, Encoding encoding) 
               : base(w, encoding) { }
    public NoTypeAttributeXmlWriter(string filename, Encoding encoding) 
               : base(filename, encoding) { }

    bool skip;

    public override void WriteStartAttribute(string prefix, 
                                             string localName, 
                                             string ns)
    {
        if (ns == "http://www.w3.org/2001/XMLSchema-instance" &&
            localName == "type")
        {
            skip = true;
        }
        else
        {
            base.WriteStartAttribute(prefix, localName, ns);
        }
    }

    public override void  WriteString(string text)
    {
        if (!skip) base.WriteString(text);
    }

    public override void WriteEndAttribute()
    {
        if (!skip) base.WriteEndAttribute();
        skip = false;
    }
}
...
XmlSerializer xs = new XmlSerializer(typeof(BaseType), 
                                     new Type[] { typeof(DerivedType) });

xs.Serialize(new NoTypeAttributeXmlWriter(Console.Out), 
             new DerivedType());

// prints <BaseType ...> (with no xsi:type)