Deep understanding :XML and serialization and deserialization of objects

  • 2020-06-12 08:36:51
  • OfStack

This article focuses on the serialization and deserialization of XML and objects. And will attach 1 some simple serialization and deserialization methods, for everyone to use.
Suppose we have two such classes in an Web project


public class Member 
    {
      public string Num { get; set; }
      public string Name { get; set; }
    }
    public class Team
    {
       public  string Name;
       public  List<Member> Members { get; set; }
    }

Suppose we want to take an instance of the Team class POST to an instance of URL,
Of course, this can be done using Form to hide the domain commit.
What if the Team contains 30 pieces of data?
To distinguish each Member, we have to suffix the name of the parameter. This requires 1 large string of hidden fields:

<!-- use Razor To demonstrate the -->
@model Team
<form id="submitForm" action="http://www.johnconnor.com/team" method="post">
<input type="hidden" name="TeamName" value="@Model.Name" />
<input type="hidden" name="MemberNum1" value="@Model.Members[0].Num" />
<input type="hidden" name="MemberName1" value="@Model.Members[0].Name" />
...
<!-- omit 28X2 a input The label -->
<input type="hidden" name="MemberNum30" value="@Model.Members[29].Num" />
<input type="hidden" name="MemberName30" value="@Model.Members[29].Name" />
</form>
<script type="text/javascript">
    document.getElementById("submitForm").submit();
</script>

Can you imagine if Team was 1 more complicated and nested 1 more?
Well, even if you're willing to do that, the other person will get a headache when they see a chunk of parameter name.
We all know that objects cannot be transferred directly over a network, but there are remedies.
XML(Extensible Markup Language) extensible markup language is itself designed to store data, and any 1 object can be described using XML. Take Team class as an example:

<?xml version="1.0" encoding="utf-8"?>
<Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Development</Name>
  <Members>
    <Member>
      <Num>001</Num>
      <Name>Marry</Name>
    </Member>
    <Member>
      <Num>002</Num>
      <Name>John</Name>
    </Member>
  </Members>
</Team>

Thus, one XML document represents one instance of Team1.
The smart ones should already have in mind that XML can be used as a vehicle for object information to be transmitted over the network because it is textual.
How do you convert an XML document to an object?

The XmlSerializer class does just that.
Namespace: ES42en.Xml.Serialization
Assembly: ES46en.Xml (in ES48en.xml.dll)
There is now an EncodeHelper class that provides serialization and deserialization methods.
The Deserialize method converts the XML string to an object of the specified type;
The Serialize method converts the object to an XML string.

/// <summary>
    ///  provide xml Document serialization   deserialization 
    /// </summary>
    public sealed class EncodeHelper
    {
        /// <summary>
        ///  deserialization XML String is of the specified type 
        /// </summary>
        public static object Deserialize(string Xml, Type ThisType)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(ThisType);
            object result;
            try
            {
                using (StringReader stringReader = new StringReader(Xml))
                {
                    result = xmlSerializer.Deserialize(stringReader);
                }
            }
            catch (Exception innerException)
            {
                bool flag = false;
                if (Xml != null)
                {
                    if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())))
                    {
                        flag = true;
                    }
                }
                throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.", 
                Xml, flag, ThisType.FullName), innerException);
            }
            return result;
        }
        /// <summary>
        ///  serialization object The object of XML string 
        /// </summary>
        public static string Serialize(object ObjectToSerialize)
        {
            string result = null ;
            try
            {
            XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType());

            using (MemoryStream memoryStream = new MemoryStream())
            {
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));
                xmlTextWriter.Formatting = Formatting.Indented;
                xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize);
                xmlTextWriter.Flush();
                xmlTextWriter.Close();
                UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true);
                result= uTF8Encoding.GetString(memoryStream.ToArray());
            }
            }
            catch (Exception innerException)
            {
                throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException);
            }
            return result;
        }
    }

To use this class, you need to add the following reference
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
Let's use a console program to demonstrate how this class works. Here is the program's Main function.

static void Main(string[] args)
        {
            List<Member> Members = new List<Member>();
            Member member1 = new Member { Name = "Marry", Num = "001" };
            Member member2 = new Member { Name = "John", Num = "002" };
            Members.Add(member1);
            Members.Add(member2);
            Team team = new Team { Name = "Development", Members = Members };
            var xml =EncodeHelper.Serialize(team);// serialization 
            Console.Write(xml);// Print serialized XML string 
            Console.ReadLine();
            Team newTeam = EncodeHelper.Deserialize(xml, typeof(Team)) as Team;// Deserialization requires explicit cast 
            Console.WriteLine("Team Name:"+newTeam.Name);// Displays the deserialized version newTeam object 
            foreach (var member in newTeam.Members)
            {
                Console.WriteLine("Member Num:" + member.Num);
                Console.WriteLine("Member Name:" + member.Name);
            }
            Console.ReadLine();
        }

After executing the line Console. Write(xml), you will see the printed XML document.

<?xml version="1.0" encoding="utf-8"?>
<Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Development</Name>
  <Members>
    <Member>
      <Num>001</Num>
      <Name>Marry</Name>
    </Member>
    <Member>
      <Num>002</Num>
      <Name>John</Name>
    </Member>
  </Members>
</Team>

The example I gave at the beginning of this article is 1 module 1.
The final deserialized newTeam object is printed out like this.
Team Name:Development
Member Num:001
Member Name:Marry
Member Num:002
Member Name:John
Going back to our example of Web communication at the beginning,
Using XML serialization and deserialization for object passing, we only need to pass the object serialization to XML string, using 1 hidden field for form submission can be done!
The receiver then deserializes the received XML string into the default object. The premise is that both parties must agree on the serialization and deserialization processes 1, and that the objects are the same.

Finally, let's look at how 1 can take advantage of the features of 1 to control the process of serialization and deserialization operations. Let's change the first class to 1:

public class Member
    {
        [XmlElement("Member_Num")]
        public string Num { get; set; }
        public string Name { get; set; }
    }
    [XmlRoot("Our_Team")]
    public class Team
    {
        [XmlIgnore]public string Name;
        public List<Member> Members { get; set; }
    }

Then we execute the console program again, and the serialization results look like this:

<?xml version="1.0" encoding="utf-8"?>
<Our_Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Members>
    <Member>
      <Member_Num>001</Member_Num>
      <Name>Marry</Name>
    </Member>
    <Member>
      <Member_Num>002</Member_Num>
      <Name>John</Name>
    </Member>
  </Members>
</Our_Team>

The original root node Team became Our_Team, the children of Member became Member_Num, and the Name children of Team were ignored.
The visible feature XmlRoot controls the display and operation of the root node, while XmlElement is for the children. If some members are marked XmlIgnore, they are ignored during serialization and deserialization.
The details of these features can be found in MSDN, but I won't go into details.
With this knowledge, passing object data over the network should not be a problem. ^_^


Related articles: