What I have is a custom settings file that I serialize/deserialize using an XmlSerializer
. I have no schema defined and no serialization tags in my object definition, just straight object serialization (although I will add them if needed).
My issue is that I need to add data members to the object. If I do that I know that the old settings file will not deserialize.
Is there a way to specify default values for the added members or some simple way to ignore them if they are missing from the XML?
In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...
The logical OR operator ( || ) returns the boolean value true if either or both operands is true and returns false otherwise.
-= Subtract AND assignment operator, It subtracts right operand from the left operand and assign the result to left operand. C -= A is equivalent to C = C - A.
From MSDN
Best Practices To ensure proper versioning behavior, follow these rules when modifying a type from version to version:
When adding a new serialized field, apply the OptionalFieldAttribute attribute.
When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute.
For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable.
I have tried to simulate your case where in new version of class have new member named Element2. initialized my new member to "This is new member" here is full proof
Test1 assumes you serialized with old definition of Root class with Just one Element1
Test2 when you serialized and de serialized with new definition of Root Class
To answer your question any way to provide default values you should use "OptionalField"
using System;
using System.Runtime.Serialization;
using System.IO;
public class Test
{
[Serializable]
public class Root
{
[OptionalField(VersionAdded = 2)] // As recommended by Microsoft
private string mElement2 = "This is new member";
public String Element1 { get; set; }
public String Element2 { get { return mElement2; } set { mElement2 = value; } }
}
public static void Main(string[] s)
{
Console.WriteLine("Testing serialized with old definition of Root ");
Console.WriteLine(" ");
Test_When_Original_Object_Was_Serialized_With_One_Element();
Console.WriteLine(" ");
Console.WriteLine("Testing serialized with new definition of Root ");
Console.WriteLine(" ");
Test_When_Original_Object_Was_Serialized_With_Two_Element();
Console.ReadLine();
}
private static void TestReadingObjects(string xml)
{
System.Xml.Serialization.XmlSerializer xmlSerializer =
new System.Xml.Serialization.XmlSerializer(typeof(Root));
System.IO.Stream stream = new MemoryStream();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(xml);
stream.Write(bytes, 0, bytes.Length);
stream.Position = 0;
Root r = (Root)xmlSerializer.Deserialize(stream);
Console.WriteLine(string.Format("Element 1 = {0}", r.Element1));
Console.WriteLine(string.Format("Element 2 = {0}", r.Element2 == null ? "Null" : r.Element2));
}
private static void Test_When_Original_Object_Was_Serialized_With_One_Element()
{
TestReadingObjects(@"<Root> <Element1>1</Element1> </Root>");
}
private static void Test_When_Original_Object_Was_Serialized_With_Two_Element()
{
TestReadingObjects(@"<Root> <Element1>1</Element1> <Element2>2</Element2> </Root>");
}
}
// here is the output
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With