对象能在不同的框架版本之间进行序列化/反序列化吗?

5
我需要使用.NET 4.0的BinaryFormatter序列化一个对象,并将其作为字节数组通过SOAP发送到在.NET 3.5下运行的Web服务。反之亦然。我已经测试过这种情况,看起来可以正常工作。
SO上有一个旧的问题,涉及到.NET 1.x和2.0的情况,这并没有让我对这种方法充满信心。
所以它在我的测试中可行,但我无法测试每个可能的对象变化,因此我需要一些理论基础。
作为一项规则,对象能否在不同的框架版本间进行序列化/反序列化?这是被接受的场景还是只是在我的情况下奏效的黑客行为?

你使用的序列化类型是什么(二进制,XML,JSON等)? - Justin Niessner
我认为你必须停止成为“AngryHacker”,变成“JollyHacker”才能让这个最好地运作 :) - Mark Schultheiss
你确切地使用了哪种序列化器?这对回答问题非常重要。 - Marc Gravell
“二进制”并不能完全回答这个问题。多个序列化器会写入非文本输出;有些可以很好地工作(如protobuf-net、BSON等),而有些甚至在单个框架版本上也不太可靠(如BinaryFormatter等)。到底哪一个呢? - Marc Gravell
@MarcGravell 抱歉,是 BinaryFormatter 格式化程序。正在更新问题。 - AngryHacker
3个回答

1
如果序列化格式是XML(SOAP)或JSON,那么它应该绝对没有问题。我不确定二进制序列化对象会有什么反应。

1
序列化的最大问题是当你有不存在的基元时。该问题存在于转换为本地代码中的某些类型时,因此它不是在服务中发现的唯一问题(假设)。
作为一个“规则”,您可以跨框架版本甚至向使用Java、Delphi和COBOL编写的客户端进行序列化(前提是具有Web服务功能的版本,并且通过服务端点适当地公开了序列化对象)。
我正在思考.NET中是否有任何在1.x中不存在的基元,因为它们可能会出现问题。任何您尝试序列化的新框架对象也将是问题所在。在2.0中,您的危险要小得多(或许不存在?)。
您的序列化越“开放”(即,像JSON、SOAP等标准 - 简化:JSON或XML,在大多数情况下),就越不可能出现问题。如果您遇到问题,可以编写自动代理等代码来解决。随着向二进制的转变,您可能会在使用WCF序列化的4.0对象与Remoting客户端之间出现一些不兼容性。

我使用二进制序列化器进行序列化,并通过SOAP传输。您能否提供一个例子(即使是理论上的),在那里会有不兼容性? - AngryHacker
不是很确定。如果您正在序列化您的领域对象(而不是来自.NET Framework的东西)并坚持使用自1.x以来存在的基元类型(例如,避免使用可空类型),我认为即使使用二进制序列化,您也不会有问题。基本上,如果您正在传递状态(具有属性的基本对象和不太多其他内容的getter和setter)并坚持使用常见的基元类型,那么您应该没问题。 - Gregory A Beamer
而且,从架构上讲,如果你已经超出了“简单”模式,你可以为你的1.x客户端恢复到基于SOAP的终端点。 :-) ::: 真是喜欢WCF的灵活性。 - Gregory A Beamer
我认为你误读了我的问题。在这个方程中,我没有任何WCF或1.x客户端。只有标准的Web服务连接3.5/4.0部分。 - AngryHacker

1
如果你所说的“二进制”是指BinaryFormatter,那么它已经在版本之间极其不容忍,因为它严格绑定于类型元数据(除非你使用自定义绑定)。因此,只有当两端使用完全相同的实现时,它才是严格可靠的。即使将属性从自动实现的属性更改为/from也会导致破坏性变化。
这不是“二进制”的失败,而是BinaryFormatter的一个特点。其他二进制序列化器没有这个问题。例如,protobuf-net可以在操作系统之间、框架之间等工作——因为格式a:不关心你的具体类型,b:固定于已发布的规范。
如果你目前正在使用BinaryFormatter:那么我认为是的,你应该明确地测试每个API。因为任何类型都可能改变实现细节。不幸的是,由于BF有通过事件等方式引入意外数据的习惯,即使这样也不一定足以验证真实的使用情况。

我正在通过网络传输的对象被隔离到一个单独的程序集中(编译为.NET 3.5)。客户端和服务器都有完全相同的程序集副本,因此像属性更改之类的事情不是问题。此外,这些对象是纯数据传输对象,例如没有事件或类似的东西。在这种情况下,我是安全的吗? - AngryHacker
1
@AngryHacker,我敬佩你的良好规划和前瞻性思维。这将使你远离痛苦的世界。有了这样的设置,我会期望它能够工作。如果失败了,那将令人惊讶,但是:偶尔也会发生意外。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接