9

我已将我的 Web 服务转换为具有一些数据合同的 wcf 服务。作为最佳实践,提到并建议 DataContracts 应该从 IExtensibleDataObject 继承。我的意思是,在添加或删除数据成员的情况下,IExtensibleDataObject 很有帮助。但我无法了解客户将如何访问已删除的数据成员。这是我的代码:

[ServiceContract(Namespace = "http://mycompany.com/2010/08/")]
public class MyWebService {
    [OperationContract]
    public Employee Add(Employee emp)
    {
        // Some Processing
    }
}

[DataContract(Name = "Employee", Namespace = "http://mycompany.com/2010/08/")]
public class Employee : IExtensibleDataObject {
    [DataMember] public string FirstName;
    [DataMember] public string LastName;

    public ExtensionDataObject ExtensionData  { get; set; }
}

现在,在我的下一个 Web 服务版本中,我对 DataContract 进行了一些更改

[DataContract(Name = "Employee", Namespace = "http://mycompany.com/2010/09/")]
public class Employee : IExtensibleDataObject {
    [DataMember] public string FirstName;
    [DataMember] public string LastName;
    [DataMember(IsRequired = true)] public string MiddleName;

    public ExtensionDataObject ExtensionData  { get; set; }
}

但是,正在访问旧版本 Web 服务的客户端现在由于未提供 MiddleName 字段而出现错误。我仍然对 IExtensionDataObject 的使用感到困惑。

4

3 回答 3

15

这是 IExtensibleDataObject 的错误使用。您已经在服务器端修改了数据合同,并且您已将新字段标记为必填项,因此这意味着您已经破坏了版本控制并且没有任何帮助。

IExtensibleDataObject 用于其他目的。假设您已修改您的客户端,以便客户端上的数据合约包含 MiddleName。现在设置 MiddleName 并使用 Add service 操作。返回的 Employee 对象中 MiddleName 的值是多少?如果您不使用 IExtensibleDataObject,则该值将为空,如果您使用 IExtensibleDataObject,则该值将与您设置为输入参数的值相同。

使用 DataContractSerializer 时,WCF 会丢弃所有无法理解的参数。IExtensibleDataObject 通过将所有这些参数存储在特殊集合中并将它们发送回客户端来避免这种情况。

如果您想使用合同版本控制,请忘记必填字段。这是破坏它的第一件事。

于 2010-08-08T20:42:43.167 回答
12

恐怕这不是 IExtensibleDataObject 的正确用法,IExtensibleDataObject 接口旨在支持版本往返,请阅读这篇关于前向兼容性的 MSDN 文章:

http://msdn.microsoft.com/en-us/library/ms731083.aspx

这是另一篇关于数据合同版本控制最佳实践的文章:http: //msdn.microsoft.com/en-us/library/ms733832.aspx

于 2010-08-08T22:28:53.743 回答
0

使 ExtensionData 属性为“虚拟”,如下所示:

public virtual ExtensionDataObject ExtensionData
{
    get { return theData; }
    set { theData = value; }
}
于 2014-01-13T14:17:29.100 回答