2010-08-26 11 views
7

Ich habe eine Basisklasse mit DataMember-Eigenschaften darin. Ich habe auch eine abgeleitete Klasse mit DataMember-Eigenschaften darin. In meinem WCF-Projekt gebe ich die abgeleitete Klasse zurück. Gibt es eine Möglichkeit für mich zu verhindern, dass ein Mitglied in meiner Basisklasse serialisiert? Hier ist ein Beispielcode:WCF DataContract Ausschluss von DataMembers Serialisierung in abgeleiteten Klassen

public class BaseClass 
{ 
    public string ShortDescription {get;set;} 
    public string LongDescription {get;set;} 
} 

public class DerivedClass : BaseClass 
{ 
    public List<Description> Descriptions {get;set;} 
} 

In diesem Code Ich möchte in der Lage sein, die geerbten Mitglieder Kurze inhaltliche Beschreibung und longdescription zu verstecken, weil sie jetzt veraltet sind. Versuche, dies zu tun, waren nicht erfolgreich. Hier ist, was ich habe versucht:

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    // override the base class members 
    [IgnoreDataMember]  
    public override string ShortDescription {get;set;} 
    [IgnoreDataMember] 
    public override string LongDescription {get;set;} 
} 

und

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    // shadow the base class members 
    [IgnoreDataMember]  
    public new string ShortDescription {get;set;} 
    [IgnoreDataMember] 
    public new string LongDescription {get;set;} 
} 

Keiner dieser Ansätze gearbeitet haben. Der Typ "DerivedClass" bei der Ausgabe in die WSDL enthält weiterhin die Elemente "Ignored" des Basisklassentyps.

Sie fragen sich vielleicht, warum ich nicht nur die Basisklasse ändere. Dies liegt daran, dass ich die Basisklasse immer noch in ihrer ursprünglichen Form als vorherige Version des Typs für die WSDL verwende, um die Abwärtskompatibilität für die Benutzer zu unterstützen. Auf diese Weise kann ich einen v1000-Aufruf haben, der BaseClass zurückgibt, und einen V1010-Aufruf, der eine DerivedClass zurückgibt. Ich kann die Funktionalität der DerivedClass hinzufügen und ändern, ohne dass ich die Möglichkeit habe, die Benutzer der v1000-Funktionalität zu beeinflussen.

Antwort

2

Schließlich fand ich einen geeigneten Weg, um diese Aufgabe zu bewältigen. Ich habe den Code nicht vor mir, also werde ich die Syntax erweitern. Es ist eine ziemlich einfache Lösung, aber sie löst das spezifische Problem, das ich hatte.

public class BaseClass 
{ 
    // leave this guy empty 
} 

public class DerivedClassVersion1 : BaseClass 
{ 
    [DataMember] 
    public string ShortDescription {get;set;} 

    [DataMember] 
    public string LongDescription {get;set;} 
} 

public class DerivedClassVersion2 : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 
} 

Badda bing! Ziemlich einfach, aber es ist was ich brauchte.

0

Try this:

public class BaseClass 
{ 
    [DataMember] 
    public virtual string ShortDescription {get;set;} 

    [DataMember] 
    public virtual string LongDescription {get;set;} 
} 

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    public override string ShortDescription {get;set;} 
    public override string LongDescription {get;set;} 
} 

EDIT: Vielleicht Nachricht Verträge unter Verwendung genau die Serialisierung zu steuern, funktionieren könnte: http://msdn.microsoft.com/en-us/library/ms730255.aspx

Sie können aber auch einen 'WCF-Router' Blick in die Umsetzung, die es Ihnen ermöglichen würde denselben Endpunkt verwenden, aber verschiedene Versionen an verschiedene Dienste weiterleiten.

+1

Dies führt zu demselben Ergebnis. Interessanterweise wird das Überschreiben und Bereitstellen des Attributs [DataMember], um es in der XML-Definition für die DerivedClass anzuzeigen, nicht in der DerivedClass, sondern in der Basisklasse angezeigt. – omatase

+0

Hrmmpf ... yep, das funktioniert nicht;) – Kwal

6

Versuchen Sie, das Attribut [DataContract] beiden Klassen hinzuzufügen. Dies teilt dem Serializer die Attribute [DataMember] und [IgnoreDataMember] mit. Ohne die Klasse, der [DataContract] zugeordnet wird, werden alle öffentlichen Mitglieder serialisiert.

[DataContract] 
public class BaseClass 
{ 
    [IgnoreDataMember] 
    public string ShortDescription {get;set;} 

    [IgnoreDataMember] 
    public string LongDescription {get;set;} 
} 

[DataContract] 
public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 
} 

Auch wäre es sogar besser sein, einen Namespace zu Ihrem Datacontracts hinzuzufügen, indem es in der [Datacontract (Namespace = „...“)] Attribut angeben. Das würde alte Clients, die Ihren aktualisierten Dienst aufrufen, unterbrechen.

+0

Bemerkenswert, dass WITH [DataContract] für die Klasse nicht mehr benötigt das explice [IgnorDataMember] - da nur Mitglieder mit [DataMember] in den Transport einbezogen werden. – Ricibob