影响客户端的 WCF 合同更改

Posted

技术标签:

【中文标题】影响客户端的 WCF 合同更改【英文标题】:WCF contract changes that affect clients 【发布时间】:2010-10-12 14:19:27 【问题描述】:

我很好奇是否有人可以概述服务器端哪些类型的 WCF 合同(接口)更改会破坏尝试发送消息的客户端,以及为什么。我相信 WCF 可以处理某些差异,但我不确定哪些可以安全更改,哪些不能安全更改。

在 OperationContract 中添加/删除参数? 添加/删除/更改 DataContract 的序列化属性? 从 ServiceContract 添加/删除 OperationContract?

一位朋友在这里提出了类似的问题:

Does adding a method to a WCF ServiceContract break existing clients?

编辑:正如 John Saunders 指出的那样,更改合同通常不是一个好主意,但有些内置的东西允许某些版本容差(ExtensionDataObject 等?)。我只是想知道版本容差有多灵活。

【问题讨论】:

【参考方案1】:

在 dasBlonde 上查看这篇文章:Versioning WCF Service Contracts

它列出了哪些更改会破坏现有客户端:

    删除操作 更改操作名称 移除操作参数 添加操作参数 更改操作参数名称或数据类型 更改操作的返回值类型 通过显式使用 .NET 属性或自定义序列化代码更改参数类型(数据协定)或操作(消息协定)的序列化 XML 格式 修改服务操作编码格式(RPC Encoding vs. Document Literal)

This article by Michele 更详细地解释了如何设计更灵活的合约。

【讨论】:

谢谢,这正是我想要的 如果你需要做这些事情之一,update your clients。使用 VS2015 很容易。 将不可为空的 Guid 合同属性设为可空会破坏客户端吗? 命名空间怎么样?命名空间更改会破坏合同吗?毕竟会被序列化一样的【参考方案2】:

合同设计建议

    第一版

    1.1。仔细选择所有合约的名称(接口、方法、类和属性)。这些在未来的版本中将很难更改。

    1.2。请记住,将来无法更改以下内容:方法参数的数量;参数类型/返回值/不受您控制的类型的属性。

    下一个版本

    2.1。如果已经存在,请勿更改任何 xxxContractAttribute 上的 Namespace 或 Name 参数。

    2.2。如果已经存在,请勿更改 DataMemberAttribute 的 Order 属性。

    2.3。只允许以下更改:

    将方法(OperationContract)添加到接口(ServiceContract)

    接口上的重命名方法

    重命名类(DataContract)

    将属性 (DataMember) 添加到类 (DataContract)

    重命名类的属性

    2.4。任何删除都会破坏兼容性。

    2.5。任何其他更改都会破坏兼容性。

这里有几个有用的链接:

WCF Versioning Guidelines Service Versioning Best Practices: Data Contract Versioning Collection Types in Data Contracts

【讨论】:

【参考方案3】:

WCF 中的“从 OperationContract 添加/删除参数”并不总是会破坏您的客户端,但您必须知道自己在做什么。 特别是,向操作合约添加新参数将导致旧客户端不传递它们,并且在服务端将设置它们的默认值。 此外,从操作合约中删除参数,从客户端的角度来看是无声的,并且在服务端将被简单地忽略。 当然,更改参数的名称/类型会导致客户端崩溃。

【讨论】:

【参考方案4】:

好的。题。由于命名语法错误(参数用大写字母指定),我想调整一些代码:

[OperationContract]
public void Foo(string Bar)

[OperationContract]
public void Foo(string bar)

会调整资金中断合同吗?

【讨论】:

是的,但是如果您只需要小写的条来用于代码目的,我认为您可以使用 [MessageParameter(Name ="Bar")] 来装饰参数本身,这使得它在客户端看起来相同,但在内部与您的服务不同。【参考方案5】:

我认为最好的做法是将合同视为牢不可破的,嗯,合同。发布后不要更改它们。使用您想要的更改创建新合同并在新端点上公开新合同很容易。

【讨论】:

我同意不更改合同的总体概念,但是如果您对合同进行小的更改,我不知道为每个新合同发布一个新端点是否总是一个好主意。对此有什么想法吗? 我的想法是,“给他们一英寸,他们就会走一英里”。不要养成允许“小”改变的习惯,否则它们会做出大改变。

以上是关于影响客户端的 WCF 合同更改的主要内容,如果未能解决你的问题,请参考以下文章

使用 WCF 中的任务构建异步操作合同的正确方法

在 WCF 双工合同中检测客户端死亡

WCF 数据合同

WCF - 在合同列表中找不到合同名称

wcf 决策:一项服务多项合同或多项服务

如何在数据合同 WCF 中使用枚举