我在客户端看到了以下情况的序列化问题。
假设我们的服务代码中包含以下类和方法
[DataContract]
public class Derived
{
[DataMember]
public string A { get; set; }
[DataMember]
public string B { get; set; }
[DataMember]
public string C { get; set; }
[DataMember]
public string D { get; set; }
}
并且服务接口具有方法
[OperationContract]
Derived GetDerived();
方法的实施 -
public Derived GetDerived()
{
var d = new Derived() {A = "A", B = "B", C = "C", D = "D"};
return d;
}
对于这个WCF服务,如果我创建客户端代理(通过添加服务引用)并执行GetDerived()调用,一切正常。
让我们稍微改变服务代码中的实体
[DataContract]
public class Base
{
[DataMember]
public string B { get; set; }
}
[DataContract]
public class Derived : Base
{
[DataMember]
public string A { get; set; }
[DataMember]
public string C { get; set; }
[DataMember]
public string D { get; set; }
}
所以在这种情况下我创建了一个新的Base类并将属性'B'移动到Base类。在客户端使用相同的旧代理,如果我执行GetDerived调用,我看不到A在客户端正确序列化的值。但是,先前版本的SOAP消息和当前版本是相同的(仅更改了订单)。我遇到了这篇http://msdn.microsoft.com/en-us/library/ms729813.aspx文章解释了这个顺序。由于我将'B'移动到基类,我无论如何都不会在派生类中控制它的顺序。
这个问题有解决方法吗?这打破了与客户端的向后兼容性。
另一方面,如果我添加新属性,假设C1为Derived类(或任何现有类),它也会更改顺序。为什么这不打破客户?与我之前提到的情景相比。
答案 0 :(得分:0)
使用上面的例子,我重载了属性" B"在派生类中,让它引用Base类(我在VB中工作,抱歉):
#region "This shenanigans prevents breaking the contract when moving some properties to the base class.
<DataMember()> Public Overloads Property B() As String
Get
Return MyBase.B
End Get
Set(value As String)
MyBase.B = value
End Set
End Property
#End Region
这样我的基类方法仍然可以在B上运行。如果我们开始实现wcf版本控制,或者还有其他需要更改契约,我可以去掉派生类中的重载,一切都应该只是工作
-JG