【问题标题】:WCF contract changes that affect clients影响客户端的 WCF 合同更改
【发布时间】: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 等?)。我只是想知道版本容差有多灵活。

【问题讨论】:

    标签: wcf datacontract servicecontract operationcontract


    【解决方案1】:

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

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

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

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

    【讨论】:

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

    合同设计建议

    1. 第一版

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

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

    2. 下一个版本

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

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

      2.3。只允许以下更改:

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

      • 接口上的重命名方法

      • 重命名类(DataContract)

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

      • 重命名类的属性

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

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

    这里有几个有用的链接:

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        [OperationContract]
        public void Foo(string Bar){}
        

        [OperationContract]
        public void Foo(string bar){}
        

        会调整资金中断合同吗?

        【讨论】:

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

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

        【讨论】:

        • 我同意不更改合同的总体概念,但是如果您对合同进行小的更改,我不知道为每个新合同发布一个新端点是否总是一个好主意。对此有什么想法吗?
        • 我的想法是,“给他们一英寸,他们就会走一英里”。不要养成允许“小”改变的习惯,否则它们会做出大改变。
        猜你喜欢
        • 1970-01-01
        • 2016-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多