One of the solutions in our company consumes a 3rd party service. Communication is done through XML messaging. On our end, we generate classes to be used based on XML schemas that they provide us, and at some point we serialize some of those types into a binary blob in our database for later use.
The problem comes in where that 3rd party company has changed one of the fields from a boolean to an integer type. Now when we try to deserialize the data that's already there we predictably get a type conversion exception (can't convert from boolean to integer).
My question is - how do we go about deserializing the existing data in our database with the old boolean type to convert it to the new integer type?
I've tried a number of things - among which were reflection and implementing ISerializable, but nothing's panned out so far. The ideal solution would be to implement ISerializable, but I get a "Member not found" error when trying to deserialize the existing data because it was already serialized using only the Serializable attribute.
Any suggestions are welcome!
Edit: Adding some code to clearly demonstrate my problem.
namespace ClassLibrary
{
[Serializable]
public class Foo //: ISerializable
{
public bool Bar { get; set; }
public Foo() { }
//[OnDeserializing()]
//internal void OnDeserializingMethod(StreamingContext context)
//{
// Bar = 10;
//}
//public Foo(SerializationInfo info, StreamingContext context)
//{
// Bar = (int)info.GetValue("Bar", typeof(int));
//}
//public void GetObjectData(SerializationInfo info, StreamingContext context)
//{
// info.AddValue("Bar", Bar);
//}
}
}
namespace ConsoleApplication2
{
static class Program
{
static void Main(string[] args)
{
Foo foo;
// Run #1, where Foo.Bar is a boolean
foo = new Foo();
foo.Bar = true;
SerializeObject(foo);
byte[] data = File.ReadAllBytes(@".\Test.bin");
foo = DeserializeObject(data) as Foo;
// Now change Foo.Bar to an integer type, comment the lines above, and uncomment the two lines below
//byte[] newData = File.ReadAllBytes(@".\Test.bin");
//foo = DeserializeObject(newData) as Foo;
Console.WriteLine(foo.Bar);
Console.ReadLine();
}
private static Object DeserializeObject(byte[] buff)
{
if (buff == null) return null;
BinaryFormatter formatter = new BinaryFormatter();
formatter.Binder = new CustomSerializationBinder();
MemoryStream ms = new MemoryStream(buff);
return formatter.Deserialize(ms);
}
private static void SerializeObject(Object obj)
{
if (obj == null) return;
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream ms = new FileStream(@".\Test.bin", FileMode.Create))
{
formatter.Serialize(ms, obj);
}
}
}
XmlSerializer
,DataContractSerializer
, or something else? – EellikeSystem.Xml
and inspecting the nodes manually) - next time better either include aVersion
field into your binary serialized class or don't serialize into Binary (with theBinaryFormatter
or what it's called) – BlauBinaryFormatter
for storing to the database, andXmlSerializer
for communications. Is that right? – Eellike