XmlSerializer

In XMLSerialization, we convert the data into the format of an XML document, which can then be transferred easily across the network.

During deserialization, we can render an object from the same XML document format. XMLSerializer is based upon Simple Object Access Protocol (SOAP), a protocol for exchanging information with web services. 

While working with XmLSerlializer, we must mark our classes with the Serializable tag to inform the compiler that this class is serializable. Please refer to the following code implementation wherein we are using this tag against our class to inform the compiler that the class is Serializable:

[Serializable]
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
public Student()
{
}
public Student(string firstName, string lastName, int Id)
{
this.FirstName = firstName;
this.LastName = lastName;
this.ID = Id;
}
}

In the preceding code implementation, we declared a Student class and specified it with the FirstName, LastName, and ID attributes. To inform the compiler that the class is serializable, we have used the Serializable tag on the class. 

Sometimes, we need to pick and choose the attributes that we would like to be serialized. In these cases, we can use the NonSerialized tag on the attribute and convey to the compiler that the attribute will not be serializable. Following is the code implementation for this:

[Serializable]
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
[NonSerialized()]
public int ID;
}

We used the Serializable tag on the class name but used the NonSerialized tag to indicate that the ID attribute cannot be serialized. 

Let's go through a code implementation scenario where we will look at a code base in which we will serialize a class object using XmlSerializer and will save the file on the filesystem. This file can then be transferred across the network:

XmlSerializer serializer = new XmlSerializer(typeof(Student));
string fileName = "StudentData";
using (TextWriter writer = new StreamWriter(fileName))
{
Student stu = new Student("Jacob", "Almeida", 78);
serializer.Serialize(writer, stu);
}

In the preceding code example, we are using the same Student class we used in the previous example. We have created a dummy Student object and are then serializing the object into bytes. The bytes are then converted into a file using the TextWriter object. 

Once the preceding code gets executed, a file with the name StudentData gets created in the system:

If we open the file in Internet Explorer, we will see the student data in XML format:

In the preceding code example, there was no hierarchy in the data. All of the data is represented as an element in the XML file. However, in most situations, we will need to represent data that is following some sort of hierarchy. Using the preceding example, let's try to represent the course scores for each of the students as well. Let's say there are five courses: English, Maths, Physics, Chemistry, and Computers. Now, let's try to represent the scores for each of the courses for the student using the following code implementation:

[Serializable]
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID;
[XmlIgnore]
public string Feedback { get; set; }
[XmlArray("CourseScores")]
[XmlArrayItem("Course")]
public List<CourseScore> CoursePerformance { get; set; }
public void CreateCoursePerformance()
{
Course phy = new Course { Name = "Physics", Description =
"Physics Subject" };
CourseScore phyScore = new CourseScore { Course = phy,
Score = 80 };
List<CourseScore> scores = new List<CourseScore>();
scores.Add(phyScore);
this.CoursePerformance = scores;
}
}
[Serializable]
public class CourseScore
{
[XmlElement("Course")]
public Course Course;
[XmlAttribute]
public int Score;
}
[Serializable]
public class Course
{
[XmlAttribute]
public string Name;
public string Description;
}
The preceding complete code can be found in the GitHub repository for this chapter.

In the preceding code implementation, we declared three classes:

  • Course: To represent the subject along with the description
  • CourseScore: To represent the score that a student is getting in that particular course
  • Student: Has a list of CourseScore to represent the score the student gets in each subject
Please note the following tags we used in the classes:
  • XmlIgnore: We use this tag against attributes that we don't want to be saved in the generated XML class. In the preceding class example, we have used XmlIgnore against the Feedback class. This will ensure that the Feedback attribute will not be present in the generated XML file.
  • XmlElement: We can use this tag if we want to represent an element in the generated XML. The element can then have attributes. In the preceding example, we used the XmlElement tag for the Course attribute. This will then enable us to add attributes of Course Name and Course Description in the generated XML file.
  • XMLArray: We use this tag when there can be multiple child records in this element. In the preceding example, we used the XMLArray tag for the CourseScores attribute to indicate that this is an element in the XML that can have multiple child records. 
  • XMLArrayItem: We use this tag to represent the individual child records in the XMLArray record. In the preceding example, we used the XMLArrayItem tag to represent individual records in the list collection variable, CourseScores.

If we need to serialize the data using XMLSerialization, we can use the following code. Once the code is executed, it will generate an XML file based on the data structure and tags used in the preceding declaration of the class:

XmlSerializer serializer = new XmlSerializer(typeof(Student));
string fileName = "StudentDataWithScores";
using (TextWriter writer = new StreamWriter(fileName))
{
Student stu = new Student("Jacob", "Almeida", 78, "Passed");
stu.CreateCoursePerformance();
serializer.Serialize(writer, stu);
writer.Close();
}

Once the program is generated, note that an XML file, StudentDataWithScores, is generated. Now, open the XML file and review the following:

Please note the following points in the structure of the XML file that is generated:

  • In the XML file, there is no node for Feedback as it has been marked with the XmlIgnore tag in the Student class file.
  • In the Student node, there is a CourseScores element node in line with the XmlArray tag that we used in the CourseScore list collection.
  • In the element node, CourseScores, we have an individual node item element, Course, in line with XmlArrayItem, which we declared for each element in the CourseScores collection.

Each of the child item nodes has a Score attribute. It is in line with the tag—XmlElement—that we used for CoursePerformance; note that the XML also shows the name and description of the course. 

Even though we're using XMLSerialization, we can produce data that we can easily read, but there are certain issues with regard to XmlSerialization:

  • It consumes more space. If we are sharing XML files, they will ultimately end up saving space on the filesystem, which might not be ideal.
  • In addition to that, if we declare an attribute with the access modifier of private, it will not be picked during the XML serialization. For example, if we set the access modifier of the LastName attribute in the preceding example, we will see that the generated XML file will not have the attribute. 

The following code is the updated set of access modifiers for the attributes in the Student class:

public string FirstName { get; set; }
private string LastName { get; set; }
public int ID;
[XmlIgnore]
public string Feedback { get; set; }
[XmlArray("CourseScores")]
[XmlArrayItem("Course")]
public List<CourseScore> CoursePerformance { get; set; }

The access modifier for the LastName attribute has been changed from public to private. If we execute the project and open the XML file, we will observe that the LastName attribute no longer exists in the generated XML file:

In the next section, we will go through the binary serialization approach in C#.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.181.57