2011-03-11 21 views
5

Mam klasę podstawową z właściwością wirtualną i typem pochodnym, która zastępuje właściwość wirtualną. Typ może być serializowany do XML. Co staram się zrobić, to NIE utrzymywać właściwości List of items, gdy obiekt jest typu pochodnego. Aby to osiągnąć, klasa pochodna dekoruje nadpisaną właściwość z atrybutem [XmlIgnore]. Właściwość wirtualna w klasie bazowej NIE stosuje atrybutu XmlIgnore. Z jakiegoś powodu lista elementów jest przekształcana do postaci szeregowej, nawet gdy obiekt jest typu pochodnego (DynamicCart).Ignorowanie właściwości na klasach pochodnych przy użyciu XmlSerializer .NET

Po zastosowaniu atrybutu XmlIgnore do właściwości wirtualnej w klasie bazowej lista nie zostanie przekształcona do pliku.

public class ShoppingCart 
{ 
    public virtual List<items> Items{get; set;} 

    //and other properties 

    public void SerializeToXML (string filePath) 
    { 
    var xmlSerializer = new XmlSerializer(this.GetType()); 
    textWriter = new System.IO.StreamWriter(filePath); 
    xmlSerializer.Serialize(textWriter, this); 
    textWriter.Flush(); 
    textWriter.Close(); 
    } 
} 

//A cart that is populated by algo based on parameters supplied by user. I have no need to 
//persist the actual items across sessions. 
class DynamicCart: ShoppingCart 
{ 
    [XmlIgnore] 
    public override List<items>{get;set;} 
    //and other properties 
} 

class Shop 
{ 
    ShoppingCart cart = new DynamicCart(); 
    PopulateCart(cart); 
    cart.serializeToXML(<PATH TO FILE>); 
} 
+0

Wygląda na to, że sam odpowiedziałeś na to pytanie. –

+0

Wdrożyłem pracę, ale nie jestem odpowiedzią na moje pytanie, dlaczego XMLSerializer nie honoruje atrybutu [XMLIgnore] w klasie z podziałem na klasy i zawiera obiekt List , gdy serializuję DynamicCart? – Ken

Odpowiedz

-1

Zgadnij, że musisz zadeklarować typ pochodny w klasie bazowej dla serializacji XML. Brzmi trochę głupio, ale jest według specyfikacji.

Zobacz ten MSDN page i patrzeć na poniższym przykładzie:

[System.Xml.Serialization.XmlInclude(typeof(Derived))] 
public class Base 
{ 
    // ... 
} 
+0

Dodanie tego atrybutu do klasy nie rozwiązało problemu. Serializer kontynuował przekształcanie do postaci szeregowej listy , nawet jeśli nadpisywana właściwość klasy pochodnej miała atrybut [XMLIgnore]. W końcu skończyłem; usunięcie nadpisanej właściwości z klasy pochodnej; i pisanie warunkowej logiki serializacji w klasie bazowej w celu zastosowania atrybutu XMLIgnore, jeśli wywodząca się klasa jest serializowana. – Ken

+0

Jakakolwiek przyczyna, dla której serwilizer nie honoruje atrybutu [XMLIgnore] w mojej klasie pochodnej? – Ken

-1

Spróbuj

XmlSerializer serializer = new XmlSerializer(typeof(DynamicCart), new Type[]{typeof(ShoppingCart)}); 

ten pozwoli Ci dodać tyle rodzajów, chcesz serializer do inclusde.

0

Wydaje mi się, że twój serializator używa twojej klasy bazowej zamiast wyprowadzonej.

public void SerializeToXML(string filePath, Type type) 
{ 
    xmlSerializer = new XmlSerializer(type); 
    textWriter = new System.IO.StreamWriter(filePath); 
    xmlSerializer.Serialize(textWriter, this); 
    textWriter.Flush(); 
    textWriter.Close(); 
} 

class Shop 
{ 
    ShoppingCart cart= new DynamicCart(); 
    PopulateCart(cart); 
    cart.serializeToXML(<PATH TO FILE>, typeof(DynamicCart)); 
} 
0

Można to zrobić, dodając wirtualną metodę ShouldSerialize*** do klasy bazowej. Na przykład:

[XmlInclude(typeof(Sub))] 
public class Base 
{ 
    public virtual string Prop { get; set; } 

    public virtual bool ShouldSerializeProp() { return true; } 
} 

public class Sub : Base 
{ 
    public override string Prop { get; set; } 

    public override bool ShouldSerializeProp() { return false; } 
} 

internal class Program 
{ 
    private static void Main() 
    { 
     var o = new Sub { Prop = "Value" }; 

     var baseSer = new XmlSerializer(typeof (Base)); 
     var subSer = new XmlSerializer(typeof (Sub)); 

     Console.Out.WriteLine("BASE:"); 
     baseSer.Serialize(Console.Out, o); 
     Console.Out.WriteLine(); 

     Console.Out.WriteLine("SUB:"); 
     subSer.Serialize(Console.Out, o); 
     Console.Out.WriteLine(); 

     Console.ReadLine(); 
    } 
} 

To daje (sprzątana nieznacznie):

BASE: 
<Base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Sub"> 
    <Prop>Value</Prop> 
</Base> 

SUB: 
<Sub /> 

Metoda musi zawierać dokładną nazwę obiektu do rozważenia po ShouldInclude....

Powiązane problemy