WCF 版本控制枚举

发布于 2024-10-11 22:49:24 字数 419 浏览 1 评论 0原文

我正在开始编写一些需要向前兼容和兼容的 WCF 数据协定。可版本化。我一直在此处阅读MSDN文章,想知道是否有人对有关枚举的第 14 点进行了澄清。内容如下:

14. 您不应在版本之间添加或删除枚举成员。您也不应该重命名枚举成员,除非您使用 EnumMemberAttribute 属性上的 Name 属性来使它们在数据协定模型中的名称保持相同。

读到这里,我的意思是,一旦枚举被发布(并被客户端使用),你就不能在不破坏兼容性的情况下以任何方式修改它(主要是添加/删除)? (即这将是一个重大变化)

有人可以证实这一点吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鱼窥荷 2024-10-18 22:49:24

我建议不要通过 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,而不是枚举。例如,WeekdayEnum 可以通过通过简单的 DTO 发送值来替换:

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

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

这样,您的旧客户就会保持满意。

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.

江南烟雨〆相思醉 2024-10-18 22:49:24

我可以确认,只要您在与服务通信时不使用新值,就可以添加到已发布的枚举而不破坏兼容性。但请注意,如果您实际尝试将类发送到使用新枚举值的服务,您将收到 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.

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文