Summary of. NET serialization knowledge

Source: Internet
Author: User
Tags net serialization

What is serialization and deserialization?

Serialization refers to the process of storing the status of the object instance to the storage media. In this process, first convert the Public and Private fields of the object and the name of the class (including the Assembly where the class is located) to the byte stream, and then write the byte stream into the data stream. When the object is deserialized, a copy identical to the original object will be created.

When two processes perform remote communication, they can send different types of data to each other. Regardless of the type of data, it is transmitted on the network in the form of binary sequence. The sender needs to convert the object to a byte sequence before it can be transmitted over the network. The receiver needs to restore the byte sequence to an object.

  • The process of converting an object into a byte sequence is calledObject serialization.
  • The process of restoring a byte sequence to an object is calledObject deserialization.

 

What are the functions of serialization?

1. Persistence object

Through serialization, we can easily save the object instance on the disk, and then restore it to an object instance through deserialization.

  • The Common Language Runtime (CLR) manages the distribution of objects in the memory, and the. NET Framework usesReflection provides an automatic serialization mechanism.
  • After the object is serialized,The class name, assembly, and all data members of the class instance are written to the storage media..
  • Objects usually use members.Variable to store references to other instances.
  • After the class is serialized,The serialization engine tracks all serialized referenced objects.To ensure that the same object is not serialized multiple times.
  • The serialization architecture provided by the. NET Framework can automatically and correctly process object charts and circular references.The only requirement for object charts is that all objects referenced by objects being serialized must be marked as Serializable.(See Basic serialization ). Otherwise, an exception occurs when the serialization program attempts to serialize unlabeled objects. When deserializing A serialized class, the class is re-created and the values of all data members are automatically restored.

 

2. Transmit the object's byte sequence on the network.

  • ObjectValid only in the application domain of the created object.
  • Unless the object is derived from MarshalByRefObject or marked as Serializable, any attempt to pass the object as a parameter or return it as a result will fail.
  • If the object is marked as Serializable, the object will be automatically serialized,And transfer from one application domain to another application domainAnd then deserialize the object to generate an exact copy of the object in the second application domain.This process is usually called value-based mail.
  • If the object is derived from MarshalByRefObject,The object reference is passed from an application domain to another application domain, rather than the object itself.
  • You can also mark the object derived from MarshalByRefObject as Serializable. When this object is used remotely, the formatting program that is responsible for serialization and is pre-configured as SurrogateSelector controls the serialization process and replaces all objects derived from externalbyrefobject with a proxy. If it is not pre-configured as SurrogateSelector, the serialization architecture will follow the following standard serialization rules.

 

. NET provides serialization Methods

  • XML Serializer
  • SOAP Serializer
  • Binary Serializer

 

Serialization instance demonstration

1. To make a class Serializable, the simplest way is to mark it with the Serializable attribute, as shown below:
[Serializable]
Public class MyObject
{
Public int n1 = 0;
Public int n2 = 0;
Public String str = null;
}

Note:

  • The Serializable attribute cannot be inherited.
  • If a new class is derived from MyObject, the new class must also be marked with this attribute; otherwise, serialization will fail. A SerializationException is displayed, indicating that the type is not marked as serializable.

 

2. BinarySerializer example
Serialize an instance of this type into a file:

MyObject obj = new MyObject ();
Obj. n1 = 1;
Obj. n2 = 24;
IFormatter formatter = new BinaryFormatter ();
Stream stream = new FileStream ("MyFile. bin", FileMode. Create,
FileAccess. Write, FileShare. None );
Formatter. Serialize (stream, obj );
Stream. Close ();

Deserialization:

IFormatter formatter = new BinaryFormatter ();
Stream stream = new FileStream ("MyFile. bin", FileMode. Open,
FileAccess. Read, FileShare. Read );
MyObject obj = (MyObject) formatter. Deserialize (fromStream );
Stream. Close ();

Note:

  • The BinaryFormatter used aboveHighly Efficient, which can generate extremely compact byte streams.
  • All objects serialized using this formatting program can also be deserialized using it. This formatting program is undoubtedly an ideal tool for deserializing objects that will be deserialized on the. NET platform.
  • Note that,The constructor is not called when the object is deserialized.. This constraint is added to deserialization for performance considerations.
  • However, this violates some runtime conventions used by object writers. Therefore, when marking objects as serializable, developers should ensure that this special convention is taken into account.

3. XMLSerializer example
Serialize an instance of this type into an Xml file.

XmlSerializer ser = new XmlSerializer (obj. GetType ());
Ser. Serialize (new FileStream (@ "users. xml", FileMode. Create), obj );

Deserialization:

XmlSerializer serializer = new XmlSerializer (Type. GetType ("MyObject "));
MyObject my = (MyObject) serializer. Deserialize (new FileStream (@ "users. xml", FileMode. Open ));

 

4. SOAP Serializer
If portability is required, use SoapFormatter. All you need to do is change BinaryFormatter in the above Code to SoapFormatter, while the calls of Serialize and Deserialize remain unchanged.

<SOAP-ENV: Envelope
Xmlns: xsi = http://www.w3.org/2001/XMLSchema-instance
Xmlns: xsd = "http://www.w3.org/2001/XMLSchema"
Xmlns: SOAP-ENC = http://schemas.xmlsoap.org/soap/encoding/
Xmlns: SOAP-ENV = http://schemas.xmlsoap.org/soap/envelope/
SOAP-ENV: encodingStyle =
Http://schemas.microsoft.com/soap/encoding/clr/1.0
Http://schemas.xmlsoap.org/soap/encoding"
Xmlns: a1 = "http://schemas.microsoft.com/clr/assem/ToFile">

SOAP-ENV: Body>
<A1: MyObject id = "ref-1">
<N1> 1 </n1>
<N2> 24 </n2>
<Str id = "ref-3"> some strings </str>
</A1: MyObject>
SOAP-ENV: Body>
SOAP-ENV: Envelope>

 

5. Differences between BinarySerializer and XMLSerializer (. NET comes with two methods for serializing objects, Xml and binary)

  • Binary serialization maintains type fidelity, which is useful for retaining the state of objects between different calls of an application.. For example, objects can be shared between different applications by serializing objects to the clipboard. You can serialize an object to a stream, disk, memory, or network. Remote Processing uses serialized "pass through value" to pass objects between computer or application domains.
  • XML serialization only serializes public attributes and fields, and does not maintain type fidelity.This is useful when you want to provide or use data without limits on applications that use the data. Because XML is an open standard, it is a good choice for sharing data through the Web. SOAP is also an open standard, making it an attractive choice.
  • The two processes are basically the same, both of which are based on the factory model,
  • XML serialization does not convert methods, indexers, private fields, or read-only attributes (except for read-only sets). YesUse BinaryFormatter to serialize all fields and attributes of an object (public and private ).Instead of using XML serialization (see ms-help: // MS. NETFramework. v1_chs/dv_fxserialization/html/8c63200d-db63-4a03-a93d-21641623df62.htmXML and SOAP serialization ).

 

Advanced serialization skills

1. Serializable attributes cannot be inherited

Note that the Serializable attribute cannot be inherited. If a new class is derived from MyObject, the new class must also be marked with this attribute; otherwise, serialization will fail. For example, if you try to serialize the following class instances, a SerializationException is displayed, indicating that the MyStuff type is not marked as serializable.

Public class MyStuff: MyObject
{
Public int n3;
}
The serialization attribute is very convenient, but it has some restrictions described above. For more information about when to mark classes for serialization (because classes cannot be serialized after compilation), see the description (see serialization rules below ).

2. serialization rules

Selective serialization
The class usually contains fields that should not be serialized.For example, assume that a class uses a member variable to store the thread ID. When this class is deserialized, the thread corresponding to the ID stored in the serialization class may no longer run, so serialization of this value is meaningless.YesMark member variables by using the NonSerialized attribute to prevent them from being serialized, As shown below:

[Serializable]
Public class MyObject
{
Public int n1;
[NonSerialized] public int n2;
Public String str;
}

Custom serialization
You can useImplement the ISerializable interface on the object to customize the serialization Process.This function is especially useful when the value of the member variable becomes invalid after deserialization, but you need to provide the value for the variable to recreate the complete state of the object..

To implement ISerializable, you must implement the GetObjectData method and a special constructor. This constructor is used in deserialization of objects.The following code example shows how to implement ISerializable on the MyObject class mentioned in the previous section.

[Serializable]
Public class MyObject: ISerializable
{
Public int n1;
Public int n2;
Public String str;

Public MyObject ()
{
}

Protected MyObject(SerializationInfo info, StreamingContext context)
{
N1 = info. GetInt32 ("I ");
N2 = info. GetInt32 ("j ");
Str = info. GetString ("k ");
}

Public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
Info. AddValue ("I", n1 );
Info. AddValue ("j", n2 );
Info. AddValue ("k", str );
}
}

  • When calling GetObjectData during serialization, you need to fill in the SerializationInfo object provided in the method call.
  • OnlyAdd the variable to be serialized as a name/value pair. Its name can be any text. As long as the serialized data is sufficient to restore the object during the deserialization process, you can freely select the member variable added to SerializationInfo. IfIf the base object implements ISerializable, the derived class should call the GetObjectData method of the base object.

 

  • It should be emphasized that when you add ISerializable to a class,GetObjectData and special constructor must be implemented simultaneously.
  • If GetObjectData is missing, the compiler sends a warning. However, the constructor cannot be implemented forcibly, so no warning is given when the constructor is missing. If you try to deserialize a class without a constructor, an exception will occur.
  • To eliminate potential security and version control problems,The current design is better than the SetObjectData method. For example, if you define the SetObjectData method as part of an interface, this method must be a public method, so that you have to write code to prevent multiple calls to the SetObjectData method. As you can imagine, if an object is performing some operations, but a malicious application calls the SetObjectData method of this object, it will cause some potential troubles.

 

  • In the deserialization process, use the constructor provided for this purpose to pass SerializationInfo to the class.
  • During object deserialization, any visibility constraints on constructors are ignored. Therefore, classes can be marked as public, protected, internal, or private.
  • A good way is to mark the constructor as protect if the class is not encapsulated. If the class has been encapsulated, it should be marked as private.
  • To restore the object state, you only need to use the name used during serialization to retrieve the value of the variable from SerializationInfo. If the base class implements ISerializable, you should call the base class constructor so that the base object can restore its variables.
  • If a new class is derived from the class that implements ISerializable, the constructor and the GetObjectData method must be implemented as long as the new class contains any variable to be serialized.

The following code snippet shows how to use the MyObject class shown above to complete this operation.

[Serializable]
Public class ObjectTwo: MyObject
{
Public int num;

Public ObjectTwo (): base ()
{
}

Protected ObjectTwo(SerializationInfo si, StreamingContext context ):
Base (si, context)
{
Num = si. GetInt32 ("num ");
}

Public override void GetObjectData(SerializationInfo si,
StreamingContext context)
{
Base. GetObjectData (si, context );
Si. AddValue ("num", num );
}
}

Remember to call the base class in the deserialization constructor. Otherwise, the constructor on the base class will never be called, and the complete object cannot be constructed after deserialization.

 

  • Objects are completely re-built, but calling methods in the deserialization process may bring adverse side effects, because the called methods may reference object references that are not deserialized at the call fashion.
  • If the deserialization class implements IDeserializationCallback, The OnSerialization method is automatically called after the entire object chart is deserialized. All referenced sub-objects are completely restored.
  • Some classes do not use the above event listeners, so it is difficult to deserialize them. The hash is a typical example.. It is very easy to retrieve keyword/value pairs during deserialization. However, the classes derived from the hash cannot be deserialized, therefore, some problems may occur when these objects are added to the return list. Therefore, we recommend that you do not call methods on the hash table.

Serialization procedure

When the Serialize method is called on the formatting program, Object serialization follows the following rules:

  • Check whether the formatting program has a proxy selector. If yes, check whether the proxy Selector Processes objects of the specified type. If the Selector Processes this object type, ISerializable. GetObjectData is called on the proxy selector.
  • If no proxy selector is available or you do not process this type, you will check whether the Serializable attribute is used to mark the object. If it is not marked, SerializationException is thrown.
  • If the object has been correctly marked, check whether the object has implemented ISerializable. If implemented, GetObjectData is called on the object.
  • If the object does not implement Serializable, the default serialization policy is used to serialize all fields not marked as NonSerialized.

 

Version Control

The. NET Framework supports version control and side-by-side execution. If the class interfaces are consistent, all classes can work across versions. Serialization involves member variables rather than interfaces. Therefore, exercise caution when adding or deleting a member variable to a class to be serialized across versions. This is especially true for classes that do not implement ISerializable. If the status of the current version changes (such as adding member variables, changing the variable type, or changing the variable name), it means that if existing objects of the same type are serialized using an earlier version, then they cannot be deserialized.

If the object state needs to change between different versions, the class author can have two options:

1) Implement ISerializable. This allows you to precisely control the serialization and deserialization processes and correctly add and interpret future states during the deserialization process.

2) use the NonSerialized attribute to mark unimportant member variables. This option can be used only when the expected class changes between different versions. For example, after adding a new variable to a higher version of the class, you can mark the variable as NonSerialized to ensure the class is compatible with earlier versions.

Serialization rules

Since classes cannot be serialized after compilation, serialization should be considered when designing new classes. The following issues need to be considered:

  • Must this class be sent across application domains? Do you want to remotely use this class? How will users use this class? Maybe they will generate a new class to be serialized from my class. As long as this possibility exists, classes should be marked as serializable.

It is recommended to mark all classes as serializable except in the following cases:

  • All classes will never span application domains. If a class does not require serialization but must span application domains, derive this class from MarshalByRefObject.
  • Class storage only applies to the special pointers of its current instance.For example, if a class contains uncontrolled memory or file handles, make sure that these fields are marked as NonSerialized or not serialized at all.
  • Some data members contain sensitive information. In this case, we recommend that you implement ISerializable and only serialize the required fields.

PS: This article is a summary of personal learning. For some content, refer to relevant articles on the Internet. If you find that your personal summary has incorrect cognition or omissions, Please comment and share your comments.

 

  • Author: Liang yiming
  • Source: http://liangyiming.cnblogs.com
  • The copyright of this article is owned by the author. You are welcome to repost this article. However, you must keep this statement without the author's consent, and provide the author's name and original text link clearly on the article page. Otherwise, you will be held legally liable.

  • 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.