代码改变世界

WCF 第六章 序列化和编码 使用IExtensibleDataObject 的双向序列化

  DanielWise  阅读(703)  评论(1编辑  收藏  举报

对支持面向服务的架构来说,数据契约版本化会随着时间推移称为面向服务的一个重要方面。随着时间推移,比如创建了新的服务,它生成了一个数据契约的新版本,通过添加额外的信息。而不是重编译所有之前使用老的数据契约版本的客户端和服务端,你可能希望它们可以平滑的升级以便于可以共享公共数据,这也正是DataContractSerializer 要做的事情。如果有额外的数据,DataContractSerializer 将会抛弃额外的信息。但这并不是在所有情况下都能正常工作。如果数据被接受后又发送回给客户端,忽略任何额外数据意味着可能会丢失信息。一个例子是一个新的客户端发送数据给一个将信息存储在一个数据库中以用来在未来的某个时刻访问的旧服务。在这种情况下,如果客户端发送给服务端过程中有任何额外信息,它将在数据发送回给客户端时丢失。这也是IExentsibleDataObject接口要解决的问题。它提供一个接口给不知道数据契约的外部数据。它通过将反序列化过程中的未知数据存储到一个ExtensibleDataObject类中实现的。

  DataContractSerializer默认行为就是忽略任何未知数据,除非IExentsibleDataObject接口在契约上实现。这里有一个在一个Employee类上使用的两个数据契约。第一个在列表6.21中显示的数据契约有三个字段: FirstName, LastName和EmployeeId.第二个在列表6.22中显示的数据契约是第一个数据契约新版本,它添加了一个额外字段,SSN。

提示 确定实现了IExentsibleDataObject

可以不通过使用svcutil.exe或者添加服务引用来共享你的数据契约。这是通过向包含你的数据契约的程序集添加一个引用实现的。在这种情况相爱,确定数据契约实现了IExtensibleDataObject或者它们不支持回环序列化。

列表6.21 初始的Employee 契约

  列表6.22显示了Employee契约的一个包含了一个额外字段SSN的新版本,它实现了employee的社会安全账号。

列表6.22 新的Employee契约

列表6.21和列表6.22中的数据契约是不同的。你可能会认为使用原来数据契约的服务奖不会接受使用一个新的数据契约的客户端的通信请求。事实上,所有事情都工作的很好。原因是新数据契约中的所有字段都在原始数据契约中存在。这意味着服务端需要的所有信息都存在。这个时候发生的就是服务端忽略掉额外的数据。这可以通过下面列表6.23中显示的UpdateEmployee服务显示出来。服务生成了一个Employee实例,做一些额外的工作,然后把同样的Employee实例返回给客户端。

列表6.23 Employee更新服务

  相应的客户端代码在列表6.24显示

列表6.24 Employee更新客户端

  服务端返回的结果中不包含SSN字段。这意味着由于数据契约版本不兼容导致我们不可以发送我们的数据契约到服务端并返回。所以如何才能修改我们的服务使其接受未知数据并恰当的返回?幸运的是,WCF提供了一个方法来接收并存储未知数据。我们可以改变我们的服务端的数据契约来允许它不了解的额外的数据。为了实现这个你必须在数据契约上实现IExtensibleDataObject接口,默认是通过svcutil.exe或者添加服务引用在生成客户端代理时完成的。列表6.25显示了支持IExtensibleDataObject接口的初始Employee契约。

列表6.25 使用IExentsibleDataObject的初始数据契约

通过这个改变现在客户端可以从服务端接收SSN成员。假设这个行为是在一个面向服务架构中期望的结果,你可能为了最佳实践在所有的数据契约上实现IExtensibleDataObject接口。

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示