Soap消息在数据契约中添加新成员的影响

时间:2011-01-04 02:06:36

标签: wcf soap datacontract

在数据合同中添加新成员对所有版本的客户端都无害。这是一个众所周知的事实。

我想测试一下。

我创建了一本图书数据合约。它的第一个版本有以下成员。

public class Book
{
    [DataMember(IsRequired = false)]
    public long BookID;

    [DataMember(IsRequired = true)]
    public string Title;

    [DataMember(IsRequired = false)]
    public string Author;
}

客户端是为此版本的合同创建的。

然后我在本书中添加了另一名成员“版本”,而本书的新版本是

public class Book
{
    [DataMember(IsRequired = false)]
    public long BookID;

    [DataMember(IsRequired = true)]
    public string Title;

    [DataMember(IsRequired = false)]
    public string Author;

    [DataMember(IsRequired = false)]
    public string Edition;
}

合同的新版本与客户的旧版本完美配合。 我想在物理上看到在线肥皂消息。我已启用客户端和服务器端消息记录。

据我所知,新成员“Edition”将被视为Nil,并且会在序列化时使用。

但是在客户端的消息中,我看到了一些奇怪的内容,以下内容。

肥皂信封看起来像这样

  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
  <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.8fingergenie.com/BookShop/CheckAvailability</Action>
  <ActivityId CorrelationId="631f540a-915b-4203-8fd8-e251da2fab85" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">68a15797-124d-47f7-a85a-cf5c661e8011</ActivityId>
</s:Header>
<s:Body>
  <CheckAvailability xmlns="http://www.8fingergenie.com/">
    <book xmlns:d4p1="http://8fingergenie.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <d4p1:Author>Spensor Johnson</d4p1:Author>
      <d4p1:BookID>1</d4p1:BookID>
      <d4p1:Edition i:nil="true"></d4p1:Edition>
      <d4p1:Title>Who Moved My Cheese</d4p1:Title>
    </book>
  </CheckAvailability>
</s:Body>

我的问题是,与旧版Data合同的客户如何在进行沟通时了解版本?或者我在这里遗漏了什么。

以下是客户端Book的架构的结构。

  <xs:schema xmlns:tns="http://8fingergenie.com" elementFormDefault="qualified" targetNamespace="http://8fingergenie.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Book">
  <xs:sequence>
    <xs:element minOccurs="0" name="Author" nillable="true" type="xs:string" />
    <xs:element minOccurs="0" name="BookID" type="xs:long" />
    <xs:element name="Title" nillable="true" type="xs:string" />
  </xs:sequence>
</xs:complexType>
<xs:element name="Book" nillable="true" type="tns:Book" />

2 个答案:

答案 0 :(得分:0)

所有客户端并非无害。如果添加,删除或更改任何成员,您可以编写一个失败的客户端。

在这种情况下故意写入客户端失败的事实意味着可以编写一个在相同情况下无意中失败的客户端。

答案 1 :(得分:0)

On进一步研究我发现了以下内容。

我在客户端使用服务引用。默认情况下,服务引用将数据协定创建为从IExtensibleDataObject派生的类型。我没有注意到这将是默认值。

因为类型是从IExtensibleDataObject派生的,所以另一端的新成员被包装在ExtensionDataObject中。这就是客户了解datacontract的新成员的方式。

感谢所有试图帮助我的人。