Added support for 'DontSerialize' attribute
Introduction
Most of us know the C# .NET Xml Serializer, and it has the ability to serialize objects to XML files, but there are a lot of limitations in it such as,
- It supports only objects that marked as Serializable.
- When two or more properties share the same reference then it serializes each property to a separated node. That causes an error when trying to deserialize the object because each property will have a different reference.
- Assume the object contains a property that references to it, such as:
ArrayList list=new ArrayList();
list.Add(list);
In this case, the C# .NET serializer will fail.
- Assume the object is an array and it has more than 1000 items, these items share the same values, then the C# .NET serializer will repeat the shared values for each item.
- C# .NET serializer is very slow compared with my serializer.
So, the new serializer class will pass all the above limitations.
Using the Code
The main class for this project is XmlObjectSerializer.cs. Here is the Serialize
function:
public XmlDocument Serialize(object obj)
{
xmlDoc = new XmlDocument();
xmlDoc.AppendChild(xmlDoc.CreateElement("XmlObjectSerializer"));
xmlDoc.DocumentElement.Attributes.Append(
xmlDoc.CreateAttribute("ObjectType")).Value =
Utility.GetTypeFullName(obj.GetType());
SerializeProperty(obj, xmlDoc.DocumentElement);
return xmlDoc;
}
Here is the Deserialize
function:
public object Deserialize(string xmlText)
{
xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlText);
Type objectType =
Type.GetType(xmlDoc.DocumentElement.Attributes["ObjectType"].Value);
var childs = GetChild(xmlDoc.DocumentElement);
if (childs[0].Name == "Array")
return DeserializeIEnumerable(childs[0], objectType);
else
{
object obj = Utility.CreateInstance(objectType);
DeserializeProperty(xmlDoc.DocumentElement, obj);
return obj;
}
}
As you can see, the code is very simple and easy to use, all you have to do is call these above functions.
Here is a sample test class,
public class Human
{
public List<Human> Sons { get; set; }
public Human Parent { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public int Id { get; set; }
public Human()
{
this.Sons = new List<Human>();
}
}
static void Main()
{
Human father = new Human()
{ FirstName = "Kamal", LastName = "Qassas",BirthDate=new DateTime(1967,4,1) };
father.Sons.Add(new Human()
{ FirstName = "Ashraf", LastName = "Qassas",
BirthDate = new DateTime(1984, 5, 2), Parent = father });
father.Sons.Add(new Human()
{ FirstName = "Ayman", LastName = "Qassas",
BirthDate = new DateTime(1985, 6, 3), Parent = father });
string xml = new XmlObjectSerializer().Serialize(father).OuterXml;
Human father1 = (Human)new XmlObjectSerializer().Deserialize(xml);
}
Finally, here is the generated XML for the above example:
<XmlObjectSerializer ObjectType="XmlSerializer.Human">
<Property PropertyName="Sons">
<Array>
<ItemDefaults>
<Property PropertyName="Parent" ReferenceNode="/XmlObjectSerializer[1]" />
<Property PropertyName="LastName">Qassas</Property>
</ItemDefaults>
<Item>
<Property PropertyName="FirstName">Ashraf</Property>
<Property PropertyName="BirthDate">5/2/1984</Property>
</Item>
<Item>
<Property PropertyName="FirstName">Ayman</Property>
<Property PropertyName="BirthDate">6/3/1985</Property>
</Item>
</Array>
</Property>
<Property PropertyName="FirstName">Kamal</Property>
<Property PropertyName="LastName">Qassas</Property>
<Property PropertyName="BirthDate">4/1/1967</Property>
</XmlObjectSerializer>
Points of Interest
XML is used these days in most programming languages, so you can use the new serializer to interact with different programming languages.