Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
662 views
in Technique[技术] by (71.8m points)

.net - Prevent XmlSerializer from emitting xsi:type on inherited types

I have managed to serialize a class that inherits from a base class to XML. However, the .NET XmlSerializer produces an XML element that looks as follows:

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

This, however, causes the receiving end of a web service to choke and produce an error that amounts to: sorry we do not know "DerivedType".

How can I prevent the XmlSerializer from emitting the xsi:Type attribute? Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use the XmlType attribute to specify another value for the type attribute:

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

//produces

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

If you really want to entirely remove the type attribute, you can write your own XmlTextWriter, which will skip the attribute when writing (inspired by this blog entry):

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...