10

I'm beginning writing some WCF data contracts that need to be forward-compatible & versionable. I've been reading the MSDN article here, and was wondering if anyone has clarification on point #14 regarding enums. It reads as follows:

14. You should not add or remove enumeration members between versions. You should also not rename enumeration members, unless you use the Name property on the EnumMemberAttribute attribute to keep their names in the data contract model the same.

Reading this, I take it to mean that once an enum is published (and used by clients), you you cannot modify it in anyway (adding / removing mainly) without breaking compatibility? (i.e. this would be a breaking change)

Can someone confirm this?

Gareth
  • 2,424
  • 5
  • 26
  • 44
  • Adding enum member won't break the functionality but removing will if enum member is in use. Adding will be useful if and only if service implementation changed or new service contract is added. – hungryMind Jan 13 '11 at 08:14

2 Answers2

10

I'd recommend not sending enums over WCF interfaces. Suppose you have the following enum:

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

If you return the enum over WCF, everything will work well:

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

Add to the enum without updating the Service Reference in the client and you're still fine:

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

However, if you return the added value from the service without updating the client Service References, the legacy clients will break:

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

I've had issues with this in projects where supporting legacy clients is important. The solution has been to simply send DTOs over the WCF instead of enums. E.g. the WeekdayEnum could be replaced by sending the values over a simple DTO:

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

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

This way, your legacy clients stay happy.

Lauri Harpf
  • 1,448
  • 1
  • 12
  • 30
  • Not sure to follow. Are you saying you'd rather handle a "List" that a List? – progLearner Dec 03 '19 at 09:32
  • Handling enums is easier. If the enum changes over time, old clients will break (you need to update them). If the enum never changes or you can ensure all clients are always updated when enums change, then there should be no problems. Disclaimer: Haven't worked with WCF for some time now. – Lauri Harpf Dec 03 '19 at 14:12
  • Ok, but in cases where the enum changes, you'd rather create a List? Is that right? Or did you have something different in mind? – progLearner Dec 03 '19 at 14:26
  • 1
    Yes, that's how I'd do it. – Lauri Harpf Dec 04 '19 at 12:13
9

I can confirm that you can ADD to a published enum without breaking compatibility, as long as you don't use the new value when talking to the service. However be aware that if you actually try to send an class to the service that is using the new enum value, you will get a 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.
Ryan Sorensen
  • 645
  • 7
  • 7