2010-08-26 11 views
7

Ho una classe base con le proprietà DataMember in esso. Ho anche una classe derivata con le proprietà DataMember in essa. Nel mio progetto WCF sto restituendo la classe derivata. C'è un modo per impedirmi di serializzare un membro della mia classe base? Ecco alcuni esempi di codice:WCF DataContract Escludere DataMembers da essere serializzato in classi derivate

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

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

In questo codice voglio essere in grado di nascondere i membri ereditati shortDescription e longdescription perché sono ormai obsolete. Qualsiasi tentativo di farlo non ha avuto successo. Ecco quello che ho provato:

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;} 
} 

e

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;} 
} 

Nessuno di questi approcci hanno lavorato. Il tipo "DerivedClass" quando viene inviato al WSDL contiene ancora i membri "Ignored" del tipo di classe base.

Ci si potrebbe chiedere perché non sto solo cambiando la classe base. Questo perché utilizzo ancora la classe base nella sua forma originale come versione precedente del tipo per WSDL per supportare la retrocompatibilità per i consumatori. In questo modo posso avere una chiamata v1000 che restituisce BaseClass e una chiamata V1010 che restituisce un DerivedClass. Posso aggiungere e modificare le funzionalità di DerivedClass tutto ciò che voglio senza il potenziale per influenzare i consumatori della funzionalità v1000.

risposta

2

Alla fine ho trovato un modo adeguato per gestire questa attività. Non ho il codice di fronte a me quindi ho intenzione di modificare la sintassi. È una soluzione piuttosto semplice, ma risolve il problema specifico che stavo avendo.

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! Abbastanza semplice, ma è quello di cui avevo bisogno.

0

Prova questo:

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: Forse utilizzando contratti di messaggi per controllare con precisione la serializzazione potrebbe funzionare: http://msdn.microsoft.com/en-us/library/ms730255.aspx

In caso contrario, si può anche prendere in considerazione l'attuazione di un 'WCF Router' che permetterebbe utilizzare lo stesso endpoint, ma indirizzare versioni diverse a servizi diversi.

+1

Questo produce lo stesso risultato. È interessante notare che se eseguo l'override e fornisco l'attributo [DataMember] nel tentativo di farlo visualizzare nella definizione XML per DerivedClass, esso non viene ancora visualizzato in DerivedClass ma nella classe base. – omatase

+0

Hrmmpf ... sì, che non funziona;) – Kwal

6

Provare ad aggiungere l'attributo [DataContract] a entrambe le classi. Questo dirà al serializzatore di guardare gli attributi [DataMember] e [IgnoreDataMember]. Senza la classe attribuita con [DataContract], tutti i membri pubblici sono serializzati.

[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;} 
} 

Inoltre, sarebbe ancora meglio aggiungere uno spazio dei nomi ai vostri datacontracts specificando nella [DataContract (Namespace = "...")] attributo. Ciò potrebbe rompere i vecchi client che chiamano il servizio aggiornato.

+0

Vale la pena notare che con [DataContract] sulla classe non è più necessario l'explice [IgnorDataMember] - come solo i membri con [DataMember] saranno inclusi nel trasporto. – Ricibob

Problemi correlati