. Serialization and deserialization in net-practical skills

Source: Internet
Author: User
Tags constructor soap serialization

Serialization and deserialization I believe that we all often hear and use, and yet some people may not know: Why does this and how. NET Frameword to implement this mechanism for us, and here I also briefly talk about my understanding of serialization and deserialization.

One, what serialization and deserialization
serialization is generally a process of converting an object into a byte stream so that it can be easily saved in a disk file or database. Deserialization is the reverse process of serialization, which is the process of swapping a byte stream back to its original object.

But why do you need to serialize and deserialize such a mechanism? This problem also involves the use of serialization and deserialization,

The main uses for serialization are:

1, the state of the application is saved in a disk file or database, and the state is restored the next time the application runs. For example, ASP.net uses serialization and anti-2, serialization to save and restore session state.
3), a group of objects can easily be copied to the Windows Forms Clipboard, and then pasted back to the same or another application.
To send an object from one application domain to another by value
And if the object is serialized into an in-memory byte stream, some other techniques can be used to process the data, such as encrypting and compressing the data.

Second, serialization and reverse sequence simple use
The. Net Framework provides two kinds of serialization methods:

1), binary serialization
2), XML, and SOAP serialization
Simple use of serialization and deserialization:

Using System;
Using System.IO;

Using System.Runtime.Serialization.Formatters.Binary;

  namespace Serializable {[Serializable] public class Person {public string personname;

  [nonserialized] public string personheight;
  private int personage;
   public int Personage {get {return personage;}
  set {personage = value;}
   public void Write () {Console.WriteLine (' Person Name: ' +personname);
   Console.WriteLine ("Person Height:" +personheight);
  Console.WriteLine ("Person of Age:" + personage);
   } class Program {static void Main (string[] args) {Person person = new person ();
   Person.personname = "Jerry";
   Person.personheight = "175CM"; Person.
   personage = 22;

   Stream stream = Serialize (person); The stream is reset for demonstration purposes.
   Position = 0;

   person = null;
   person = deserialize (stream); Person.
   Write ();
   
  Console.read ();

   private static MemoryStream Serialize (person person) {MemoryStream stream = new MemoryStream ();Construct binary serialization Formatter BinaryFormatter BinaryFormatter = new BinaryFormatter ();

   Tells the serializer to serialize the object into a stream binaryformatter.serialize (stream, person);

  return stream;
   private static person deserialize (Stream stream) {BinaryFormatter BinaryFormatter = new BinaryFormatter ();
  return (person) binaryformatter.deserialize (stream);

 }
  
 }
}

The main is to invoke the Binnaryformatter class under the System.Runtime.Serialization.Formatters.Binary namespace for serialization and deserialization, invoking the resulting screenshot after the deserialization:

It can be seen that other members of the tag nonserialized can be serialized, noting that this attribute can only be applied to fields in one type and inherited by derived types.

The serialization and deserialization of SOAP and XML is similar to the above, just need to change the formatter on it, I will not list here.

Iii. control serialization and deserialization
There are two ways to implement control serialization and deserialization:

By attributes such as OnSerializing, Onserialized,ondeserializing, ondeserialized,nonserialized and Optionalfield
Implement System.Runtime.Serialization.ISerializable interface
The first way to implement control serialization and deserialization of code:

Using System;
Using System.IO;
Using System.Runtime.Serialization;

Using System.Runtime.Serialization.Formatters.Binary; namespace Controlserialization {[Serializable] public class Circle {private double radius;//RADIUS [nonserial Ized] public double;
      Area public Circle (double inputradiu) {radius = Inputradiu;
    Area = Math.PI * radius * RADIUS; [ondeserialized] private void ondeserialized (StreamingContext context) {area = Math.PI * Radius ra
    Dius
      public void Write () {Console.WriteLine ("Radius is:" + radius);
    Console.WriteLine ("Area are:" + area);
      Class Program {static void Main (string[] args) {Circle c = new Circle (10);
      MemoryStream stream =new MemoryStream ();
      BinaryFormatter formatter = new BinaryFormatter ();
      Serializing an object into a memory stream, where you can use an object of any type derived from the System.IO.Stream abstract class, where I use the MemoryStream type. Formatter.
      Serialize (STREAM,C); Stream.position = 0;
      c = null; c = (Circle) formatter.
      Deserialize (stream);
      C.write ();

    Console.read ();
 }
  }
}

The results of the operation are:

Note: If you comment out the ondeserialized attribute, the value of the area field is 0, because the area field is not serialized into the stream.

In the object that needs to be serialized above, the formatter will only serialize the value of the radius field of the object. The value in the Area field is not serialized because the field has already applied the NonSerializedAttribute property, and then we build a Circle object with Circle c=new Circle (10), internally, Area will set a value of about 314.159, when the object is serialized, only the value of the RADIUS field (10) is written to the stream, but when deserialized into a circle object, the value of its area field is initialized to 0 instead of a value of about 314.159. To solve this problem, customize a method to apply the Ondeserializedattribute property. The execution at this point is that every time an instance of the type is deserialized, the formatter checks to see if a method is defined in the type that applies the attribute, and if so, calls the method, and all serializable fields are set correctly when the method is invoked. In addition to ondeserializedattribute this custom Attribute,system. The Runtime.serialization namespace also defines these custom properties for Onserializingattribute,onserializedattribute and Ondeserializingattribute.

Implement ISerializable interface mode to control serialization and deserialization code:

Using System;
Using System.IO;
Using System.Runtime.Serialization;
Using System.Runtime.Serialization.Formatters.Binary;

Using System.Security.Permissions;
    namespace ControlSerilization2 {[Serializable] public class Myobject:iserializable {public int n1;

    Public intn2;

    [nonserialized] public String str; Public MyObject () {} protected MyObject (SerializationInfo info, StreamingContext context) {N1 = I Nfo.
      GetInt32 ("I"); N2 = info.
      GetInt32 ("J"); str = info.
    GetString ("K"); [SecurityPermissionAttribute (SecurityAction.Demand, SerializationFormatter = true)] public virtual void Getobje Ctdata (SerializationInfo info, StreamingContext context) {info.
      AddValue ("I", N1); Info.
      AddValue ("J", N2); Info.
    AddValue ("K", str);
      public void Write () {Console.WriteLine ("N1 is:" + N1);
      Console.WriteLine ("N2 is:" + N2);
    Console.WriteLine ("Str is:" + str); }} CLAss program {static void Main (string[] args) {MyObject obj = new MyObject ();
      OBJ.N1 = 2;
      OBJ.N2 = 3;
      Obj.str = "Jeffy";
      MemoryStream stream = new MemoryStream ();
      BinaryFormatter formatter = new BinaryFormatter ();
      Serializing an object into a memory stream, where you can use an object of any type derived from the System.IO.Stream abstract class, where I use the MemoryStream type. Formatter.
      Serialize (stream, obj); Stream. 
      Position = 0;
      obj = null; obj = (MyObject) formatter.
      Deserialize (stream); Obj.
      Write ();
    Console.read ();

 }
  }
}

The results are:

The execution at this point is that when the formatter serializes the object, each object is checked, and if a type of object is found to implement the ISerializable interface, the formatter ignores all custom attributes. Instead, construct a new System.Runtime.Serialization.SerializationInfo object that contains a collection of values that are actually serialized for the object. After the SerializationInfo object is constructed and initialized, the formatter invokes the GetObjectData method of the type and passes it a reference to the SerializationInfo object. The GetObjectData method is responsible for determining what information is needed to serialize the object, adding the information to the SerializationInfo object, and by calling the AddValue method to add each of the required data, and after adding all the necessary serialization information, returns to the formatter , and then the formatter gets all the values that have been added to the SerializationInfo object. and serialize them to the stream, when deserialized, when the formatter extracts an object from the stream, it allocates memory for the new object, initially all fields of the object are set to 0 or null, and then the The formatter checks whether the type implements the ISerializable interface, and if this interface exists, the formatter attempts to invoke a special constructor, whose arguments are exactly the same as the GetObjectData method.

Iv. how the formatter is serialized and deserialized
as you can see from the analysis above, serialization and deserialization are primarily the formatter, but here's how the formatter serializes an object that has the SerializableAttribute attribute applied to it.

1, the formatter calls the Formatterservices Getserializablemembers method: public static memberinfo[] Getserializablemembers (type type, StreamingContext context); This method uses the launch to obtain the public and private implementation fields of the type except for the field marked with the Nonserializedattributee property. method returns an array of MemberInfo objects in which each element corresponds to a serializable instance field.
2, the object is serialized, and the System.Reflection.MemberInfo object array is passed to the Formatterservices static method Getobjectdata:public static object[] GetObjectData (Object obj,memberinfo[] members);  This method returns an object array in which each element identifies the value of a field in the serialized object.
3, the formatter writes the assembly identity and the full name of the type to the stream.
4, the formatter then iterates through the elements in two arrays, writes each member's name and value to the stream.
The next step is to explain how the formatter automatically deserializes an object that has the SerializableAttribute property applied to it.

1. The formatter reads the assembly identity and the full type name from the stream.
2. The formatter calls the Formatterservices static method getuninitializedobject:public static Object Getuninitializedobject (Type ttype); This method allocates memory for a new object, but does not invoke the constructor for the object. However, all fields of an object are initialized to 0 or null.
The 3 formatter now constructs and initializes a MemberInfo array, calling the Formatterservices Getserializablemembers method, which returns a set of fields that are serialized and now need to be deserialized.
4. The formatter creates and initializes an object array based on the data contained in the stream.
5. Pass a reference to the newly assigned object, MemberInfo array, and parallel object array to the Formatterservices static method Populateobjectmembers:
public static object Populateobjectmembers (Object obj,memberinfo[] members,object[] data; This method iterates through the array, initializing each field to the corresponding value.

Note: The format of how serialization and deserialization objects are partially excerpted from the CLR via C # (third edition) is written here to give beginners a better understanding of what the formatter does during serialization and deserialization.

This article about serialization and deserialization is finally over, and I hope it will help my friends.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.