2011-02-18 42 views
4

不同的接口实现以下情况:如何反序列化与WCF

我们的软件与业务对象,在它们与WCF发送从服务器到客户端的时刻。

[Serializable] 
public class SomeValueBO 
{ 
    public DateTime Timestamp{ get; set; } 
} 

它们被打包在请求/响应消息中。

[DataContract] 
public class Response 
{ 
    [DataMember] 
    public List<SomeValueBO> Values { get; set; } 
} 

问题:

我们想DTO的发送到客户端,而不是业务对象的。我听说,可以在客户端检索与在服务器上发送的不同类型的实例。

例子:

public interface ISomeValue 
{ 
    DateTime Timestamp { get; set; } 
} 

[Serializable] 
public class SomeValueBO : ISomeValue 
{ 
    public DateTime Timestamp { get; set; } 
} 

[DataContract] 
public class SomeValueDTO : ISomeValue 
{ 
    [DataMember] 
    public DateTime Timestamp { get; set; } 
} 

的回应是这样的:

[DataContract] 
public class Response 
{ 
    [DataMember] 
    public List<ISomeValue> Values { get; set; } 
} 

在服务器上:

public class ServiceClass : IService 
{ 
    public Response HandleRequest(Request request) 
    { 
     Response response = new Response(); 
     response.Values.Add(new SomeValueBO()); 

     return response; 
    } 
} 

上的客户端:

Response response = serviceProxy.HandleRequest(request); 
ISomeValue value = response.Values[0]; 

value is SomeValueDTO 

我试过只声明DTO对象的已知类型和Data Contract Equivalence,但WCF仍然保持反序列化项目作为BO实例。

我要补充,这两种方式都上班,送BO和检索它作为一个BO和发送BO和检索DTO,但当然有不同的要求。

所以我的问题是,这是可能的,如果是,我究竟做错了什么?

感谢您的帮助, Enyra

编辑: 我也发现了,我们使用的是NetDataSerializer,算得上是它不工作的问题?

+1

什么是您使用的邮件协议?是否有一个原因,你不是简单地从服务器发送dto?从长远来看,这(你试图做的)可能是一个维护噩梦。 – 2011-02-18 08:01:11

+0

是的,有一个原因,我们加载值> 10'000,如果我们复制它们,它会变得很慢,所以我们会用这个技巧来转换它。 – Enyra 2011-02-18 10:49:07

回答

2

MSDN

的NetDataContractSerializer在一个 重要途径不同 从DataContractSerializer的:在 NetDataContractSerializer包括序列化的 XML中的CLR 类型信息,而DataContractSerializer不包含此类型信息。 因此,仅当串行化和反串行化结束共享相同的CLR 类型时,才可以使用NetDataContractSerializer 。

这就是为什么它目前没有工作。

如果您改为使用DataContractSerializer,则客户端和服务只需要就对象状态的序列化XML表示形式达成一致,而不是基于确切的CLR运行时类型。您需要使用DataContractAttribute来对双方的类型进行属性设置,以使与序列化表示形式相关联的XML名称空间在两侧都相同。显然,数据合约在序列化结构方面必须是等价的。

也就是说,你要做的事应该可以与DataContractSerializer一起使用。至于它是否是最好的方式 - 就像所有的设计决定“取决于”。

4

即使你没有使用NetDataContractSerializer(评论),即SomeValueBO未声明为一个数据合同的事实意味着将主要充当场串。这是特别痛因为自动实现的属性被重新场串行皇家疼痛 - 他们成为疯狂脆。

我将宣布为一个合同:

[DataContract] 
public class SomeValueBO 
{ 
    [DataMember] 
    public DateTime Timestamp{ get; set; } 
} 

,并切换到DataContractSerializer,但请注意这是重大更改 - 你会在同一时间更新所有客户端和服务器。只要他们共享完整的合同签名,您就可以拥有其他实施方式。

重新目前使用的NetDataContractSerializer - 如果这是对性能,有替代品 - 有合同基于二进制序列化是更快(CPU)和小(带宽)比NetDataContractSerializerPerformance Tests of Serializations used by WCF Bindings

+0

我也做了一些指定数据合同的尝试,在我的文章中我只使用了bo规范的原始形式。 – Enyra 2011-02-18 10:46:16