2011-01-13 75 views
8

我開始編寫一些需要正向兼容的WCF數據協定&可版本化。我一直在閱讀MSDN的文章here,並想知道是否有人對第14點關於枚舉的說明。它的內容如下:WCF版本控制示例

14.您不應該在版本之間添加或移除枚舉成員。除非您使用EnumMemberAttribute屬性上的Name屬性來保持其在數據合同模型中的名稱相同,否則您也不應重命名枚舉成員。

讀這個,我認爲一旦enum被髮布(並被客戶端使用),你不能修改它(主要是添加/刪除)而不破壞兼容性嗎? (即這將是一個突破變化)

有人可以證實這一點嗎?

+0

添加枚舉成員不會破壞功能,但如果枚舉成員正在使用,將刪除。當且僅當服務實施改變或新的服務合同被添加時,添加纔會有用。 – hungryMind 2011-01-13 08:14:32

回答

8

我可以確認您可以添加到已發佈的枚舉而不破壞兼容性,只要您在與服務交談時不使用新值即可。但是請注意,如果您實際嘗試向使用新枚舉值的服務發送一個類,則會得到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

如果服務返回包含向舊客戶端添加的值的枚舉類型的列表,這是否爲真? – 2012-09-20 16:04:50

6

我建議不超過 WCF接口發送枚舉。假設你有以下枚舉:

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

如果返回了WCF的枚舉,一切都會很好地工作:

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

添加到枚舉無需在客戶端更新服務引用和你尚精:

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

但是,如果返回從服務的附加值,而無需更新客戶端服務引用,舊版客戶端會打破

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

我在支持舊客戶端很重要的項目中遇到了問題。解決方案一直是通過WCF而不是枚舉來發送DTO。例如。通過在簡單的DTO上發送數值可以取代WeekdayEnum:

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

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

這樣,您的傳統客戶端保持高興。