【问题标题】:Adding field to WCF data contract breaks clients?向 WCF 数据合同添加字段会破坏客户端?
【发布时间】:2018-04-19 04:28:51
【问题描述】:

我有一个 WCF 服务,它返回一个实现 IExtensibleDataObject 的类。我需要向这个类添加一个新字段。我更新了 DataContract 接口并对类进行了更改。现在,当我尝试运行客户端应用程序时,出现以下错误:

无法加载文件或程序集 'xxx.yyyy.zzzz,版本=1.3.9.26111, 文化=中性, PublicKeyToken=b09e2f3e9b5894f0' 或 它的依赖项之一。位于 程序集的清单定义确实 与程序集引用不匹配。 (HRESULT 异常:0x80131040)

WFC 类的 AssemblyVersion 已更改 - 这会破坏客户端吗?

编辑:

生产中有使用此服务的客户端。如果可能的话,我不想让他们更新他们的服务参考并重新部署他们的客户来进行这个简单的更改。

【问题讨论】:

    标签: wcf


    【解决方案1】:

    这取决于您如何设置数据合同。

    在 WCF 中,使用所有默认值,您的服务将使用 DataContractSerializer (DCS) 将您的对象序列化为 XML。 DCS 将按顺序序列化您的字段 - 首先是公共字段,然后是私有字段。在每个可见性组中,它将按名称的字母顺序对字段/属性进行排序。

    因此,如果您引入一个新的公共属性 MiddleName 并且您已经拥有 FirstNameLastName,那么您会很好:旧的 XML 会是

    <YourObject>
       ....
       <FirstName>.....</FirstName>
       <LastName>.....</LastName>
    </YourObject>
    

    而您的新属性只需在末尾添加一个新属性:

    <YourObject>
       ....
       <FirstName>.....</FirstName>
       <LastName>.....</LastName>
       <MiddleName>....</MiddleName>
    </YourObject>
    

    这样的更新“在末尾添加一些东西”应该可以正常工作,DCS 只会忽略 XML 中的其他标签。

    但是:您是否引入了一个名为 Gender 的属性,该属性会卡在 &lt;FirstName&gt;&lt;LastName&gt; 之间,从而破坏 XML 中数据的顺序,从而破坏数据合同 - 没有“旧”客户端能够调用您的新服务。

    为了控制这一点,您可以将特定的Order= 属性放在数据合同中的数据成员上:

    [DataContract]
    public class SomeAddress
    {
       [DataMember(Order=0)]
       public string FirstName;
    
       [DataMember(Order=1)]
       public string LastName;
    }
    

    然后您可以轻松添加新属性 - 只需将其添加到列表末尾!

    [DataContract]
    public class SomeAddress
    {
       [DataMember(Order=0)]
       public string FirstName;
    
       [DataMember(Order=1)]
       public string LastName;
    
       [DataMember(Order=2)]
       public string Gender;
    }
    

    因此,通过在数据协定上使用Order= 属性,您可以控制您的 XML 布局,并且可以对现有数据协定进行简单的扩展而不会中断更新。

    要了解更多背景知识和深入的专业知识,您应该阅读 MSDN 杂志网站上的Serialization in Windows Communication Foundation - 强烈推荐。

    【讨论】:

    • 我会试试这个,但预期的错误是我得到的“无法加载程序集”版本吗?
    • 做到了。我没有更改任何现有成员的顺序,而是将 Order=2 添加到新成员。下一个版本将对所有新成员设置 Order=3,依此类推。
    【解决方案2】:

    从您的服务参考上下文菜单中选择...“Update Service Reference

    【讨论】:

    • 是的,这会起作用,但是我还有其他客户在生产中。我想避免让每个人都必须重新编译和重新部署 - 特别是如果他们不需要新字段。
    猜你喜欢
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2016-10-26
    • 2011-06-23
    • 2016-10-29
    • 2018-04-21
    • 2013-02-01
    • 2012-09-15
    相关资源
    最近更新 更多