In depth understanding of C serialization and deserialization

  • 2020-05-12 03:03:36
  • OfStack

Before we dive into serialization and deserialization of C#, we need to understand what serialization is, also known as serialization, which is the mechanism that the.NET runtime environment USES to support the fluidization of user-defined types. Serialization is to save an object to a file or database field, and deserialization is to convert the file to the original object when appropriate. The purpose is to persist a custom object with some kind of storage formation, or to transfer such an object from one place to another. .NET framework provides two ways of serialization:
1. It USES BinaryFormatter for serialization;
2. Serialization with SoapFormatter;
3. Use XmlSerializer for serialization.
The first provides a simple binary data stream and some additional type information, while the second formats the data stream as XML storage. The third is actually similar to the second, but much simpler than the second, XML (without the extra information specific to SOAP). You can use the [Serializable] property to flag a class as serializable. If the elements of a class do not want to be serialized, 1 and 2 can be marked with the [NonSerialized] attribute, and 2 can be marked with [XmlIgnore].
Let's take a closer look at C# serialization and deserialization:
Serialization and deserialization 1. Serialization using BinaryFormatter
Here is a serializable class:

using System;  
using System.Data;  
using System.Configuration;  
using System.Web;  
using System.Web.Security;  
using System.Web.UI;  
using System.Web.UI.WebControls;  
using System.Web.UI.WebControls.WebParts;  
using System.Web.UI.HtmlControls;  
using System.IO;  
using System.Runtime.Serialization.Formatters.Binary;  
/**////  � summary �   
/// ClassToSerialize  Summary of   
///  � /summary �   
[Serializable]  
public class ClassToSerialize  
{  
    public int id = 100;  
    public string name = "Name";  
    [NonSerialized]  
    public string Sex = " male ";  
}

The following are the methods of serialization and deserialization:

public void SerializeNow()  
{  
    ClassToSerialize c = new ClassToSerialize();  
    FileStream fileStream =   
    new FileStream("c:\\temp.dat", FileMode.Create);  
    BinaryFormatter b = new BinaryFormatter();  
    b.Serialize(fileStream, c);  
    fileStream.Close();  
}  
public void DeSerializeNow()  
{  
    ClassToSerialize c = new ClassToSerialize();  
    c.Sex = "kkkk";  
    FileStream fileStream =  
    new FileStream("c:\\temp.dat",   
    FileMode.Open, FileAccess.Read, FileShare.Read);  
    BinaryFormatter b = new BinaryFormatter();  
    c = b.Deserialize(fileStream) as ClassToSerialize;  
    Response.Write(c.name);  
    Response.Write(c.Sex);  
    fileStream.Close();  
} 

You can see the result of serialization by calling the above two methods: the Sex property is always null because it is marked [NonSerialized].
Serialization and deserialization of C# 2 serialization using SoapFormatter
Similar to BinaryFormatter, we only need to make 1 simple modification:
a. Replace.Formatter.Binary in the using statement with.Formatter.Soap;
b. Replace all BinaryFormatter with SoapFormatter.
c. Make sure the file extension is.xml
After the above simple changes, you can realize the serialization of SoapFormatter, and the resulting file is a file in xml format.
C# serialization and deserialization 3. Serialization using XmlSerializer
One more question about the formatter. Suppose we need XML but don't want the extra information specific to SOAP, what should we do? There are two options: either write a class that implements the IFormatter interface in a manner similar to the SoapFormatter class, but without the information you don't need; Either use the library class XmlSerializer, which does not use the Serializable property, but provides similar functionality.
If we want to serialize using XmlSeralizer instead of using the mainstream serialization mechanism, we need to make 1 change:
a. Add the System. Xml. Serialization namespace.
The b.Serializable and NoSerialized properties are ignored and instead use the XmlIgnore property, which behaves like NoSerialized.
c.XmlSeralizer requires a class to have a default constructor, a condition that may already be met.
Take a look at the C# serialization and deserialization examples below:
Class to serialize:

using System;  
using System.Data;  
using System.Configuration;  
using System.Web;  
using System.Web.Security;  
using System.Web.UI;  
using System.Web.UI.WebControls;  
using System.Web.UI.WebControls.WebParts;  
using System.Web.UI.HtmlControls;  
using System.Xml.Serialization; 



[Serializable]  
public class Person  
{  
    private string name;  
    public string Name  
    {  
        get 
        {  
<SPAN style="WHITE-SPACE: pre"> </SPAN>    return name;  
<SPAN style="WHITE-SPACE: pre"> </SPAN>}  
<SPAN style="WHITE-SPACE: pre"> </SPAN>set 
<SPAN style="WHITE-SPACE: pre"> </SPAN>{  
<SPAN style="WHITE-SPACE: pre"> </SPAN>    name = value;  
<SPAN style="WHITE-SPACE: pre"> </SPAN>}  
    }  

 
    public string Sex;  
    public int Age = 31;  
    public Course[] Courses;  

    public Person()  
    {  
    }  
    public Person(string Name)  
    {  
<SPAN style="WHITE-SPACE: pre"> </SPAN>name = Name;  
<SPAN style="WHITE-SPACE: pre"> </SPAN>Sex = " male ";  
    }  
}  


[Serializable]  
public class Course  
{  
    public string Name;  
    [XmlIgnore]  
    public string Description;  
    public Course()  
    {  
    }  
    public Course(string name, string description)  
    {  
<SPAN style="WHITE-SPACE: pre"> </SPAN>Name = name;  
<SPAN style="WHITE-SPACE: pre"> </SPAN>Description = description;  
    }  
} 

C# serialization and deserialization methods:

public void XMLSerialize()  
{  
    Person c = new Person("cyj");  
    c.Courses = new Course[2];  
    c.Courses[0] = new Course(" English ", " Communication tool ");  
    c.Courses[1] = new Course(" mathematics "," The natural sciences ");  
    XmlSerializer xs = new XmlSerializer(typeof(Person));  
    Stream stream = new FileStream("c:\\cyj.XML",FileMode.Create,FileAccess.Write,FileShare.Read);  
    xs.Serialize(stream,c);  
    stream.Close();  
}  
public void XMLDeserialize()  
{  
    XmlSerializer xs = new XmlSerializer(typeof(Person));  
    Stream stream = new FileStream("C:\\cyj.XML",FileMode.Open,FileAccess.Read,FileShare.Read);  
    Person p = xs.Deserialize(stream) as Person;  
    Response.Write(p.Name);  
    Response.Write(p.Age.ToString());  
    Response.Write(p.Courses[0].Name);  
    Response.Write(p.Courses[0].Description);  
    Response.Write(p.Courses[1].Name);  
    Response.Write(p.Courses[1].Description);  
    stream.Close();  
} 

Here the Description attribute value of the Course class will always be null, and the generated xml document does not have this node, as follows:

 � ?xml version="1.0"? �   
 � Person xmlns:xsi=  
"http://www.w3.org/2001/XMLSchema-instance"   
xmlns:xsd="http://www.w3.org/2001/XMLSchema" �   
   � Sex Male  �   �  /Sex �   
   � Age � 31 � /Age �   
   � Courses �   
 � Course �   
   � Name English  �   �  /Name �   
   � Description Communication tools /Description �   
 � /Course �   
 � Course �   
   � Name Mathematical  �   �  /Name �   
   � Description Natural science /Description �   
 � /Course �   
   � /Courses �   
   � Name � cyj � /Name �   
 � /Person � 

C# serialization and deserialization 4. Custom serialization
If you want the user to serialize the class, but are not completely satisfied with the way the data flow is organized, you can customize the serialization behavior by implementing the interface in the custom class. This interface has only one method, GetObjectData. This method is used to fill the SerializationInfo object with the data needed to serialize the class object. The formatter you use will construct the SerializationInfo object and then call GetObjectData when serialized. If the superclass of the class also implements ISerializable, then the superclass implementation of GetObjectData should be called. If you implement ISerializable, you must also provide a constructor with a specific stereotype, whose parameter list must be the same as GetObjectData. The constructor should be declared private or protected to prevent careless developers from using it directly. Here's an example:
C# serialization and deserialization implements ISerializable classes:

using System;  
using System.Data;  
using System.Configuration;  
using System.Web;  
using System.Web.Security;  
using System.Web.UI;  
using System.Web.UI.WebControls;  
using System.Web.UI.WebControls.WebParts;  
using System.Web.UI.HtmlControls;  
using System.Runtime.Serialization;  
using System.Runtime.Serialization.Formatters.Binary;  
/**////  � summary �   
/// Employee  Summary of   
///  � /summary �   
[Serializable]  
public class Employee:ISerializable  
{  
    public int EmpId=100;  
    public string EmpName=" Andy lau ";  
    [NonSerialized]  
    public string NoSerialString = "NoSerialString-Test";  
    public Employee()  
    {  
        //  
<SPAN style="WHITE-SPACE: pre"> </SPAN>// TODO:  Add the constructor logic here   
<SPAN style="WHITE-SPACE: pre"> </SPAN>//  
    }  
    private Employee(SerializationInfo info, StreamingContext ctxt)  
    {  
<SPAN style="WHITE-SPACE: pre"> </SPAN>EmpId = (int)info.GetValue("EmployeeId", typeof(int));  
<SPAN style="WHITE-SPACE: pre"> </SPAN>EmpName = (String)info.GetValue("EmployeeName",typeof(string));  
<SPAN style="WHITE-SPACE: pre"> </SPAN>//NoSerialString = (String)info.GetValue("EmployeeString",typeof(string));  
    }  
    public void GetObjectData(SerializationInfo info, StreamingContext ctxt)  
    {  
<SPAN style="WHITE-SPACE: pre"> </SPAN>info.AddValue("EmployeeId", EmpId);  
<SPAN style="WHITE-SPACE: pre"> </SPAN>info.AddValue("EmployeeName", EmpName);  
<SPAN style="WHITE-SPACE: pre"> </SPAN>//info.AddValue("EmployeeString", NoSerialString);  
    }  
} 

C# serialization and deserialization methods:

public void OtherEmployeeClassTest()  
{  
    Employee mp = new Employee();  
    mp.EmpId = 10;  
    mp.EmpName = " Qiu Feng ";  
    mp.NoSerialString = " How are you? ";  
    Stream steam = File.Open("c:\\temp3.dat", FileMode.Create);  
    BinaryFormatter bf = new BinaryFormatter();  
    Response.Write("Writing Employee Info:");  
    bf.Serialize(steam,mp);  
    steam.Close();  
    mp = null;  
    //C# Deserialization of serialization and deserialization   
    Stream steam2 = File.Open("c:\\temp3.dat", FileMode.Open);  
    BinaryFormatter bf2 = new BinaryFormatter();  
    Response.Write("Reading Employee Info:");  
    Employee mp2 = (Employee)bf2.Deserialize(steam2);  
    steam2.Close();  
    Response.Write(mp2.EmpId);  
    Response.Write(mp2.EmpName);  
    Response.Write(mp2.NoSerialString);  
} 

The in-depth discussion of C# serialization and deserialization is a process of experience and experimentation, so I hope this article has helped you to understand and learn about C# serialization and deserialization.

Related articles: