2011-01-13 10 views
8

Sto iniziando a scrivere alcuni contratti di dati WCF che devono essere compatibili con le versioni precedenti &. Ho letto l'articolo MSDN here e mi chiedevo se qualcuno avesse dei chiarimenti sul punto # 14 relativo alle enumerazioni. Si legge come segue:Enumerazione WCF

14. Non è necessario aggiungere o rimuovere membri di enumerazione tra le versioni. Inoltre, non rinominare i membri dell'enumerazione, a meno che non si utilizzi la proprietà Name sull'attributo EnumMemberAttribute per mantenere invariato il loro nome nel modello di contratto dati.

Leggendo questo, deduco che quando un enum viene pubblicato (e utilizzato dai client), non è possibile modificarlo in ogni caso (aggiunta/rimozione principalmente) senza rompere la compatibilità? (questo sarebbe un cambio di rottura)

Qualcuno può confermarlo?

+0

L'aggiunta di enum member non interromperà la funzionalità ma rimuoverà se il membro enum è in uso. L'aggiunta sarà utile se e solo se l'implementazione del servizio cambia o viene aggiunto un nuovo contratto di servizio. – hungryMind

risposta

8

Posso confermare che è possibile AGGIUNGERE a un enum pubblicato senza interrompere la compatibilità, purché non si utilizzi il nuovo valore quando si parla del servizio. Tuttavia, se si tenta effettivamente di inviare una classe al servizio che utilizza il nuovo valore enum, verrà visualizzato System.ServiceModel.CommunicationException.

There was an error while trying to serialize parameter myType. The InnerException message was 'Enum value 'x' is invalid for type 'myType' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'. Please see InnerException for more details. 
+0

È vero se il servizio restituisce, ad esempio, un elenco del tipo enum che contiene il valore aggiunto per un client precedente? –

6

io consiglierei non l'invio di enumerazioni oltre interfacce WCF. Supponiamo di avere il seguente enum:

[DataContract] 
public enum WeekdayEnum 
{ 
    [EnumMember] 
    Monday = 0 
} 

Se si restituisce l'enum su WCF, tutto funzionerà bene:

[ServiceContract] 
public class Service1 
{ 
    [OperationContract] 
    public List<WeekdayEnum> GetWeekdays() 
    { 
     return new List<WeekdayEnum> { WeekdayEnum.Monday }; 
    } 
} 

aggiungere alla enum senza aggiornare il Servizio di riferimento nel client e siete ancora bene:

[DataContract] 
public enum WeekdayEnum 
{ 
    [EnumMember] 
    Monday = 0, 
    [EnumMember] 
    Tuesday = 1 
} 

Tuttavia, se si torna al valore aggiunto dal servizio senza aggiornare i riferimenti client del servizio, i client legacy saranno rompere:

[ServiceContract] 
public class Service1 
{ 
    [OperationContract] 
    public List<WeekdayEnum> GetWeekdays() 
    { // NetDispatcherFaultException on legacy clients that only have Monday 
     return new List<WeekdayEnum> { WeekdayEnum.Monday, WeekdayEnum.Tuesday }; 
    } 
} 

Ho avuto problemi con questo in progetti in cui supportare i client legacy è importante. La soluzione è stata quella di inviare semplicemente DTO al WCF anziché alle enumerazioni. Per esempio. il WeekdayEnum potrebbe essere sostituito con l'invio dei valori nel corso di un semplice DTO:

[DataContract] 
public class WeekdayDto 
{ 
    [DataMember] 
    public int Id { get; set; } 

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

In questo modo, i client legacy felice soggiorno.