2009-11-13 8 views
14

Sono riuscito a serializzare una classe che eredita da una classe base in XML. Tuttavia, il .NET XmlSerializer produce un elemento XML che appare come segue:Impedire a XmlSerializer di emettere xsi: digitare su tipi ereditati

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

Questo, tuttavia, fa sì che il fine di ricevere un servizio web per soffocare e produrre un errore che ammonta a: mi dispiace che non conosciamo " DerivedType".

Come posso impedire a XmlSerializer di emettere l'attributo xsi: Type? Grazie!

risposta

17

È possibile utilizzare il XmlType attribute per specificare un altro valore per l'attributo type:

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

//produces 

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

Se davvero si vuole eliminare completamente l'attributo type, è possibile scrivere il proprio XmlTextWriter, che salterà l'attributo durante la scrittura (ispirato a 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) 
+1

ottimo! Molto apprezzato Luc. –

Problemi correlati