2011-01-13 2 views
8

Я начинаю писать некоторые контракты данных WCF, которые должны быть совместимы с прямой связью & версии. Я читал статью MSDN here и задавался вопросом, есть ли у кого-нибудь разъяснения по вопросу № 14 относительно перечислений. Он гласит:WCF Versioning Enums

14. Вы не должны добавлять или удалять элементы перечисления между версиями. Вы также не должны переименовывать элементы перечисления, если вы не используете свойство Name в атрибуте EnumMemberAttribute, чтобы сохранить их имена в модели контракта данных одинаково.

Чтение этого, я полагаю, это означает, что как только перечисление опубликовано (и используется клиентами), вы не можете его модифицировать (добавление/удаление в основном) без нарушения совместимости? (т. е. это будет изменение смены)

Может кто-нибудь подтвердить это?

+0

Добавление члена перечисления не нарушает функциональность, но удаляется, если член перечисления используется. Добавление будет полезно тогда и только тогда, когда будет изменена реализация службы или добавлен новый контракт на обслуживание. – hungryMind

ответ

8

Я могу подтвердить, что вы можете добавить ADD к опубликованному перечислению без нарушения совместимости, если вы не используете новое значение при разговоре с сервисом. Однако имейте в виду, что если вы действительно попытаетесь отправить класс службе, использующей новое значение enum, вы получите сообщение об ошибке 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

Это правда, если служба возвращает, скажем, список типа перечисления, содержащий добавленное значение для более старого клиента? –

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

Добавить в перечислении без обновления Service Reference в клиенте, и вы еще хорошо:

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

Однако, если вы возвращаете добавленную стоимость от службы без обновления клиента Service Ссылки, с устаревшими клиентами будут перерыв:

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

У меня были проблемы с этим в проектах, где поддержки устаревших клиентов важно. Решением было просто отправить DTO по WCF вместо перечислений. Например. WeekdayEnum может быть заменена отправкой значения по простому DTO:

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

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

Таким образом, ваши клиенты остаются унаследованных счастливыми.