向WCF数据合同添加字段会破坏客户端吗?

时间:2010-11-24 23:26:35

标签: wcf

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

  

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

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

修改

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

2 个答案:

答案 0 :(得分:26)

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

在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的属性,该属性会在 <FirstName><LastName>之间插入,从而会破坏数据的顺序您的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 - 强烈推荐。

答案 1 :(得分:1)

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