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?
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.