Click here to Skip to main content
15,860,972 members
Articles / Web Development / ASP.NET

XML Serialization and Deserialization: Part 1

Rate me:
Please Sign up or sign in to vote.
4.87/5 (170 votes)
2 Jan 2015CPOL5 min read 694.9K   286   78
XML serialization and deserialization using C#

Introduction

The article talks about serialization of objects in XML format and deserialization of an XML file back to an object. Serialization is a process by which an object's state is transformed in some serial data format, such as XML or binary format. Deserialization, on the other hand, is used to convert the byte of data, such as XML or binary data, to object type. Serialization is the process of converting an object into a form that can be readily transported. For example, you can serialize an object and transport it over the Internet using HTTP between a client and a server. On the other end, deserialization reconstructs the object from the stream. XML serialization results in strongly typed classes with public properties and fields that are converted to a serial format (in this case, XML) for storage or transport.

Let's start with a basic example. Here is a simple class that needs to be serialized:

C#
public class AddressDetails
{
    public int HouseNo { get; set; }
    public string StreetName { get; set; }
    public string City { get; set; }
    private string PoAddress { get; set; }
}     

The following points should be noted while creating a class for serialization:

  1. XML serialization only serializes public fields and properties.
  2. XML serialization does not include any type information.
  3. We need to have a default/non-parameterised constructor in order to serialize an object.
  4. ReadOnly properties are not serialized.

Code to serialize the above class:

C#
public static void Main(string[] args) 
{ 
    AddressDetails details = new AddressDetails();
    details.HouseNo = 4;
    details.StreeName = "Rohini";
    details.City = "Delhi";
    Serialize(details);
}   
static public void Serialize(AddressDetails details)
{ 
    XmlSerializer serializer = new XmlSerializer(typeof(AddressDetails)); 
    using (TextWriter writer = new StreamWriter(@"C:\Xml.xml"))
    {
        serializer.Serialize(writer, details); 
    } 
}

XmlSerializer (located in the System.Xml.Serialization namespace) class is used to serialize and deserialize. The class method Serialize is called. Since we have to serialize in a file, we create a "TextWriter". Since TextWriter implements IDisposable, we used using so that we need not close the writer.

The output after the serialization is:

XML
<?xml version="1.0" encoding="utf-8"?> 
XML
<AddressDetails>
  <HouseNo>4</HouseNo>
  <StreetName>Rohini</StreetName>
  <City>Delhi</City>
</AddressDetails>

Here, in the XML, we can see that the Head tag of the XML created is the same as that of the class name and the subtag names are the same as the properties in class AddressDetails. Each public property is displayed in the form of Tags in the XML created. We can observe here that only public fields are displayed here.

XML Serialization and Attributes

Some common attributes that are available during Serialization are:

  • XmlAttribute: This member will be serialized as an XML attribute.
  • XmlElement: The field will be serialized as an XML element.
  • XmlIgnore: Field will be ignored during Serialization.
  • XmlRoot: Represent XML document's root Element.

Use of XmlElement

Further, if we need to have different Tag name in XML from the class property Name. We can introduce the XmlElement attribute to it in the class structure.

C#
public class AddressDetails
{ 
    [XmlElement("Number")]
    public int HouseNo { get; set; }
    [XmlElement("Street")] 
    public  string StreetName { get; set; } 
    [XmlElement("CityName")]
}

[XmlElement("Number")] specifies that the property HouseNo will be serialized with the Tag name "Number" in the XML File. It helps us to map between the XML Tag name and the class Property Name. The resultant XML string with the Custom tag name is given below:

C#
<AddressDetails> 
  <Number>4</Number>
  <Street>Rohini</Street>
  <CityName>Delhi</CityName>
</AddressDetails>

Use of XmlAttribute

If we want that the property HouseNo should occur as the attribute for the Tag AddressDetails, then we should use XmlAttribute. XmlAttribute serializes the object property as the attribute for the parent tag. The following code illustrates the functionality:

C#
public class AddresssDetails
{ 
    [XmlAttribute]("Number")]
    public int HouseNo { get; set; }
    [XmlElement("Street")] 
    public  string StreetName { get; set; } 
    [XmlElement("CityName")]
    public string City {get; set;}
}

The XML serialized output for the code will be:

XML
<AddressDetails Number="4">
  <Street>Rohini</Street>
  <CityName>Delhi</CityName>
</AddressDetails>

Notice here, since the class property HouseNo is specified as XMLAttribute, therefore this property is an Attribute for the parent tag AddressDetails.

Use to XmlIgnore

By default, all public fields and public read/write properties are serialized by the XmlSerializer. That is, the value of each public field or property is persisted as an XML element or XML attribute in an XML-document instance. In order to override this property, apply XmlIgnore attribute to it. This will remove the element from the XML. The code below explains the following:

C#
public class AddressDetails
{
    [XmlElement("Number")]
    public int HouseNo;
    [XmlElement("Street")]
    public string StreetName;
    [XmlIgnore]
    public string City;
}

Here, we can see that the property City contains XmlIgnore attribute. The resultant XML created won't contain the City tag in it.

XML
<AddressDetails>
    <Number>4</Number>
    <Street>ABC</Street>
</AddressDetails>

Notice here that the property City is not serialized because of the attribute XmlIgnore placed on it.

Use of XmlRoot

Every XML has a root element. By default, the name of the root element is the same as the name of the class that is serialized. In order to give a custom name to the root element of XML, we use XmlRoot attribute. Implementation of this attribute is provided below:

C#
[XmlRoot("Root")]
public class AddressDetails
{
    [XmlElement("Number")]
    public int HouseNo;
    [XmlElement("Street")]
    public string StreetName;
    [XmlElement("CityName")]
    public string City;
} 

Here, we can see that the attribute XmlRoot is placed over AddressDetails class. This will now override the default serialization behavior which takes XML tag root name same as the class name. The XML will now have "Root" as the root tag.

XML
<Root>
  <HouseNo>4</HouseNo>
  <StreetName>Rohini</StreetName>
  <City>Delhi</City> 
</Root>   

Notice here that the root tag here is now "Root" and not the Class name.

Object List Serialization

Now let's try to serialize a list of AddressDetails object to XML file:

C#
public static void Main(string[] args) 
{ 
    List<AddressDetails> AddressList = new List<AddressDetails>();
    AddressDetails detail1 = new AddressDetails();
    detail1.HouseNo ="4";
    detail1.StreetName = "ABC";
    detail1.City = "Delhi";
 
    AddressDetails detail2 = new AddressDetails(); 
    detail2.HouseNo ="3";
    detail2.StreetName = "ABCD";
    detail2.City = "New Delhi";
 
    AddressList.Add(detail1); 
    AddressList.Add(detail2); 
    Serialize(AddressList); 
}   
public void Serialize(List<AddressDetails> list)
{
    XmlSerializer serializer = new XmlSerializer(typeof(List<AddressDetails>));
    using ( TextWriter writer = new StreamWriter( @"C:\Xml.txt")
    {
        serializer.Serialize(writer, list) 
    }  
}

The XML output for the above execution will be:

XML
<ArrayOfAddressDetails>
  <AddressDetails>
    <Number>4</Number>
    <Street>ABC</Street>
    <CityName>Delhi</CityName>
  </AddressDetails>
  <AddressDetails>
    <Number>3</Number>
    <Street>ABCD</Street>
    <CityName>New Delhi</CityName>
  </AddressDetails>
</ArrayOfAddressDetails>

Notice that the XML produced gives a list of AddressDetails object.

Serialization of Classes Containing Other Class Objects

If we have a class structure such that a class contains an object of other class and we want to include that class object also for serialization. Let's take a look at the following example:

C#
public class PersonalDetails
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Address address;
}
public class Address
{
    public int HouseNo { get; set; }
    public string StreetName { get; set; }
    public string City { get; set; }
}

This is how the PersonalDetails class will be serialized:

XML
<PersonalDetails>
  <Name>Mayank</Name>
  <Age>24</Age>
  <Address>
    <HouseNo>4</HouseNo>
    <StreetName>Rohini</StreetName>
    <City>Delhi</City>
  </Address>
</PersonalDetails>

To add more complexity to it, let's try creating the following XML structure:

XML
<PersonalDetails>
  <Name>Mayank</Name>
  <Age>24</Age>
  <Address HouseNo="4">
    <StreetName>Rohini</StreetName>
    <City>Delhi</City>
  </Address>
</PersonalDetails>

Observe that the difference over here is that we need to have "HouseNo" as the attribute for the Address Tag. Let's see what change will be made in class in order to create this structure:

C#
public class PersonalDetails
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Address address;
    public PersonalDetails()
    {
        Name = "Mayank";
        Age = 24;
        address = new Address();
    }    
}
public class Address
{
    [XmlAttribute("HouseNo")]
    public int HouseNo { get; set; }
    public string StreetName { get; set; }
    public string City { get; set; }
    public Address()
    {
        HouseNo = 8;
        StreetName = "Rohini";
        City = "Delhi";
    }
}

As per the requirement, we wanted to have "HouseNo" as XML attribute instead of the normal XMLElement. Therefore, we introduce "XmlAttribute" on property.

Let's try creating the following XML structure:

XML
<PersonalDetails>
  <Name>Mayank</Name>
  <Age>24</Age>
  <address HouseNo="8">Rohini</address>
</PersonalDetails>

The difference over here is that we require the StreetName as innertext of the XML node "address". So in order to create such structure, we have another attribute XmlText. This helps us to add the particular property as innertext for a tag.

So the code for creating such a structure is:

C#
public class PersonalDetails
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Address address;
}
public class Address
{
    [XmlAttribute("HouseNo")]
    public int HouseNo { get; set; }
    [XmlText]
    public string StreetName { get; set; }
}

The "XmlText" attribute here adds StreetName as InnerText to the tag "address"

Deserialization of XML

See the following article for details on deserialization: XML Serialization and Deserialization (Part 2).

Conclusion

Serialization is a very efficient way to convert the object to XML. This save lots of time and effort.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
GeneralMy vote of 5 Pin
Member 1193533025-Nov-20 14:16
Member 1193533025-Nov-20 14:16 
QuestionHow to add items to existing file instead of overwriting. Pin
enswafford13-Jul-19 10:50
enswafford13-Jul-19 10:50 
QuestionExtendedXmlSerializer will be a better choice Pin
Wojciech Nagórski7-Dec-17 1:18
Wojciech Nagórski7-Dec-17 1:18 
QuestionOrder of XML elements Pin
Member 1109066912-Oct-17 2:19
Member 1109066912-Oct-17 2:19 
QuestionXmlInclude + Controlled serialization of parent classes Pin
Olshansky23-Feb-17 8:46
Olshansky23-Feb-17 8:46 
QuestionNIce Pin
Vignesh Mani3-Aug-16 0:26
professionalVignesh Mani3-Aug-16 0:26 
GeneralSimply the best explanation Pin
Vineel K8-Jun-15 2:45
Vineel K8-Jun-15 2:45 
SuggestionSome improvements Pin
_Noctis_23-Apr-15 14:48
professional_Noctis_23-Apr-15 14:48 
GeneralRe: Some improvements Pin
Mayank_Gupta_21-Jul-16 7:23
professionalMayank_Gupta_21-Jul-16 7:23 
GeneralRe: Some improvements Pin
_Noctis_22-Jul-16 0:37
professional_Noctis_22-Jul-16 0:37 
Questionbest article Pin
Prafulla Sahu21-Apr-15 17:03
professionalPrafulla Sahu21-Apr-15 17:03 
QuestionComments in the XML? Pin
CoderJ7-Apr-15 19:23
CoderJ7-Apr-15 19:23 
QuestionPossible errors? Pin
Nitancy19-Mar-15 9:37
Nitancy19-Mar-15 9:37 
Questiongood overview, but missing coverage of use of DataContract Pin
BillWoodruff10-Jan-15 5:46
professionalBillWoodruff10-Jan-15 5:46 
GeneralMy vote of 5 Pin
atp19817-Jan-15 22:41
atp19817-Jan-15 22:41 
SuggestionCan we give the same treatment to JSON? Pin
Bob Delaney6-Jan-15 7:17
Bob Delaney6-Jan-15 7:17 
GeneralUseful article Pin
K K Srinivasan2-Jan-15 6:04
K K Srinivasan2-Jan-15 6:04 
BugBUG in VS2013 (Serialization of Lists) Pin
diordonez5-Dec-14 5:35
diordonez5-Dec-14 5:35 
Hi. First of all thanks for your great article dealing with Serialization/Deserialization process, very well done and very well explained.

There is a BUG in VS2013 that yields compilation errors in this block of code:

C#
XmlSerializer serializer = new XmlSerializer(typeof(List<AddressDetails>));
using ( TextWriter writer = new StreamWriter( @"C:\Xml.txt")
{
    serializer.Serialize(writer, list)
}




Just to let you know that VS2013 UPDATE 4 fixes this BUG and it compiles and run properly.

Regards !
GeneralVery nice - 5 star Pin
CPUser2419-Sep-14 13:27
CPUser2419-Sep-14 13:27 
GeneralNarration slang was good. Pin
SULFIKAR A N27-Aug-14 19:57
SULFIKAR A N27-Aug-14 19:57 
GeneralMy vote of 5 Pin
Maciej Los17-Jun-14 6:54
mveMaciej Los17-Jun-14 6:54 
GeneralMy vote of 5 Pin
kartin117-May-14 12:53
kartin117-May-14 12:53 
QuestionNice one! Pin
Lakswin10-Dec-13 8:26
Lakswin10-Dec-13 8:26 
AnswerRe: Nice one! Pin
Mayank_Gupta_18-Dec-13 19:24
professionalMayank_Gupta_18-Dec-13 19:24 
GeneralMy vote of 5 Pin
Member 1002155728-May-13 2:45
Member 1002155728-May-13 2:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.