Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataContractSerializer cannot deserialize after namespace changed

I have 50 classes marked with DataContractAttribute.

These classes form a huge hierarchical tree, which is serialized/deserialized using the DataContractSerializer to xml.

All of them specify a custom datacontract namespace [DataContract(Namespace="http://example.com")], except for 3 classes, which I've missed.

// Old class definitions 
[DataContract(IsReference=true)]  // <-- forgot ns
public class Type1{}
[DataContract(IsReference=true)] // <-- forgot ns
public class Type2{}
[DataContract(IsReference=true)] // <-- forgot ns
public class Type3{}
[DataContract(IsReference=true, Namespace="http://example.com")] // <-- 47 more like this
public class Type4{} 

I want these 3 classes to use the same datacontract namespace as the other 47 classes.

After the change, all my previously-saved xmls fails to load.

// Changed to:
[DataContract(IsReference=true, Namespace="http://example.com")] // <-- changed ns
public class Type1{} 
[DataContract(IsReference=true, Namespace="http://example.com")] // <-- changed ns
public class Type2{} 
[DataContract(IsReference=true, Namespace="http://example.com")] // <-- changed ns
public class Type3{} 
[DataContract(IsReference=true, Namespace="http://example.com")]
public class Type4{}

I tried this method:

DataContractSerializer - change namespace and deserialize file bound to old namespace

But got a SerializationException saying Deserialized object with reference id 'i5' not found in stream.

How can I deserialize xmls saved before and after the namespace change?

like image 774
jayars Avatar asked Jun 04 '26 09:06

jayars


1 Answers

I would personally change the data contract and then create a script that parses the previously saved xmls to add the namespace info. Quick and simple.

Something like loading xmls as string and then calling:

xmlstr=xmlstr.Replace("<Type1>", "<Type1 xmlns:Namespace=\"http://example.com\">");

Or maybe create two classes (one with the old namespace and one with the new) create a mapping method so that you can deserialize the old xmls based on the old namespace and serialize them after mapping with the new namespace.

like image 71
gerodim Avatar answered Jun 07 '26 03:06

gerodim