问题后重构code与NetDataContractSerializer反序列化 [英] Problem deserializing with NetDataContractSerializer after refactoring code

查看:299
本文介绍了问题后重构code与NetDataContractSerializer反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个情况我采用序列NetDataContractSerializer并存储在数据库中的XML作为一种方式来记住应用程序中这些对象的状态,一些.NET对象。最近我刚碰到其中,财产和类型名称一些code重构导致未能反序列化这个XML数据的第一种情况。

I have a situation where I'm serializing some .NET objects using NetDataContractSerializer and storing the XML in a database as a way to remember the state of these objects within an application. Recently I just came across the first situation where some code refactoring of property and type names has resulted in the failure to deserialize this XML data.

到目前为止,我想出了攻击如何处理版本兼容性破坏像这些一样是利用现有设施NetDataContractSerializer本身来控制反序列化或只是直接转换XML两种不同的计划。从我的实验和研究看来,人们可以使用一个定制SerializationBinder 的反序列化到不同类型和属性名称/类型的变化可以通过实施了ISerializable或解决通过实施ISurrogateSelector和ISerializationSurrogate写序列化代理。不幸的是这preferred机制还没有摇出来,除非我能证明,否则会出现使用代理人版本序列化的数据之间的移动是不可能的NetDataContractSerializer,这是由于一些原因不明的<一个href="https://connect.microsoft.com/VisualStudio/feedback/details/678627/iserializationsurrogate-loaded-from-isurrogateselector-in-netdatacontractserializer-receives-no-serializationinfo">design微软决定。微软曾建议是用两面相同的序列化这完全违背了使用一个代理在一个类型的名称更改或移动到不同的命名空间或组装的情况下帮助的目的。

So far I've come up with two different plans of attack for how to deal with version compatibility breaks such as these which are to use facilities available within the NetDataContractSerializer itself to control the deserialization or just to transform the XML directly. From my experimentation and research it appears that one can deserialize to a different type using a custom SerializationBinder and property name/type changes can be addressed by either implementing ISerializable or writing a serialization surrogate by implementing ISurrogateSelector and ISerializationSurrogate. Unfortunately this preferred mechanism hasn't panned out and unless I can be shown otherwise it appears using surrogates move between version of the serialized data is not possible with the NetDataContractSerializer and this is due to some unexplained design decision by Microsoft. What Microsoft has suggested is to use the same serialization on both sides which completely defeats the purpose of using a surrogate to aid in cases where a type name changes or it is moved into a different namespace or assembly.

要解决这个问题,请使用相同的NetDataContractSerializer实例或   另一个实例,其也与相容初始化   SurrogateSelector。

To fix it, please use the same NetDataContractSerializer instance or another instance that is also initialized with a compatible SurrogateSelector.

这说明与的MSDN文章,其中有这么一段有关使用自定义粘合剂替代类型以及处理该序列化结构等变化。

This explanation conflicts with an MSDN article which has this to say about using a custom binder to substitute types along with dealing with other changes in the serialization structure.

期间反序列化,格式器看到该粘合剂已被设定。   由于每个对象都是要被反序列化,格式化调用   粘合剂的BindToType方法,传递程序集名称和类型   格式化要反序列化。在这一点上,决定BindToType   什么类型实际上应该构建并返回此类型。

During deserialization, the formatter sees that a binder has been set. As each object is about to be deserialized, the formatter calls the binder's BindToType method, passing it the assembly name and type that the formatter wants to deserialize. At this point, BindToType decides what type should actually be constructed and returns this type.

请注意,原来的类型和新的类型必须具有相同的确切领域   名称和类型,如果新的类型使用通过简单的序列化   序列化自定义属性。然而,该类型的新版本   可以实现ISerializable接口,然后它的特殊   构造函数将被调用和类型可以检查的值   SerializationInfo中的对象,并确定如何反序列化本身。

Note that the original type and the new type must have the same exact field names and types if the new type uses simple serialization via the Serializable custom attribute. However, the new version of the type could implement the ISerializable interface and then its special constructor will get called and the type can examine the values in the SerializationInfo object and determine how to deserialize itself.

因此​​,无论我将能够得到NetDataContractSerializer工作反序列化我的V1 XML到我的V2类型,否则我将不得不手动转换XML。如果有人能证明NetDataContractSerializer的SerializationInfo中做其实工作中使用时,ISerializable的或使用序列的代理人,将是极好的,或者至少给出比一个由微软给出更好的解释,否则我可能会提出新问题辩论的最佳途径在.NET中直接改造旧XML。

So either I'm going to be able to get NetDataContractSerializer working to deserialize my V1 XML into my V2 types or I'm going to have to manually transform the XML. If somebody could prove that NetDataContractSerializer's SerializationInfo does in fact work when using ISerializable or using serialization surrogates that would be excellent or at least give a better explanation than the one given by Microsoft, otherwise I'll probably post a new question to debate the best way in .NET to transform the old XML directly.

更新2011-08-16: 一些试验后看来,ISerializable的和系列化替代技术既正常工作,如果它出现在对象图中每个字段缺少一些有价值的类型信息的连载实现了ISerializable反之型刚用[Serializable接口]的原始类型属性在附加属性的形式。

UPDATE 2011-08-16: After some experimentation it appears that the ISerializable and serialization surrogate technique both work fine if the original type that was serialized implemented ISerializable otherwise if the type just used the [Serializable] attribute it appears that each field in the object graph is missing some valuable type information in the form of extra attributes.

用例的 [Serializable接口] 属性

<OldClass2 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" z:Type="NdcsSurrogateTest.OldClass2" z:Assembly="NdcsSurrogateTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/NdcsSurrogateTest">
  <_stable z:Id="2">Remains the same</_stable>
  <_x003C_OldProperty_x003E_k__BackingField>23</_x003C_OldProperty_x003E_k__BackingField>
</OldClass2>

例实施的 ISerialzable

<OldClass2 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema" z:Id="1" z:Type="NdcsSurrogateTest.OldClass2" z:Assembly="NdcsSurrogateTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/NdcsSurrogateTest">
  <_stable z:Id="2" z:Type="System.String" z:Assembly="0" xmlns="">Remains the same</_stable>
  <_x003C_OldProperty_x003E_k__BackingField z:Id="3" z:Type="System.Int32" z:Assembly="0" xmlns="">23</_x003C_OldProperty_x003E_k__BackingField>
</OldClass2>

在反序列化使用NetDataContractSerializer与定制绑定来改变类型,然后要么实施了ISerializable该类型或提供替代选择器指定序列化代理,基本上满足了ISerializalbe作用的第一个例子,那么你将看到一个空的SerializationInfo在ISerializationSurrogate.SetObjectData方法。当处理在第二个例子中,XML SerializationInfo中似乎得到正确的信息和事物正常工作。

When deserializing the first example using the NetDataContractSerializer with a custom binder to change the type and then either implementing ISerializable on that type or providing a surrogate selector which designates a serialization surrogate which basically fulfills the ISerializalbe role then you will see an empty SerializationInfo in the ISerializationSurrogate.SetObjectData method. When processing the xml in the second example the SerializationInfo seems to get the right information and things work as expected.

我的结论是由NetDataContractSerializer为类型产生默认的XML,只有通过SerializableAttribute支持序列将不会被使用,因为缺少类型信息的ISerializable的或序列的替代技术反序列化兼容。因此,为了使使用NetDataContractSerializable以上未来证明,人们应该定制序列,以确保该类型信息被包括在XML这样以后反序列化可以在无需手动变换源XML定制

My conclusion is that the default XML produced by NetDataContractSerializer for types that support serialization only through the SerializableAttribute will not be compatible with deserialization using ISerializable or serialization surrogate techniques because of the lack of type information. So to make the use of NetDataContractSerializable more future proof, one should customize the serialization to ensure this type information is included in XML so that later deserialization can be customized without having the manually transform the source XML.

推荐答案

是的,你必须有一个深思熟虑的数据迁移路径,如果你使用的序列化。你提到的解决方案是什么,我会做个人,包括在code,将反序列化的支票。如果旧版本被检测到,做一个小的转变,因此新的格式相匹配,并根据需要进行。一旦所有的数据转换,即code可以废弃在将来的版本。

Yep, you have to have a well thought out data migration path if you're using serialization. The solution you mentioned is what I would do personally, to include a check in the code that would deserialize. If an older version is detected, do a small transformation so it matches the new format, and proceed as needed. Once all of the data is transformed, that code can be obsoleted in a future release.

这篇关于问题后重构code与NetDataContractSerializer反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆