C Programming Summary (I) Serialization Summary
- 2021-11-13 02:31:37
- OfStack
Serialization is the process of transforming the state of an object into a format that can be maintained or transmitted. The opposite of serialization is deserialization, which converts streams into objects. Combining these two processes, data can be easily stored and transmitted.
Several serialization techniques:
1) Binary serialization preserves type fidelity, which is useful for preserving the state of objects between different calls to the application. For example, you can share objects between different applications by serializing them to the clipboard. You can serialize objects to streams, disks, memory, networks, and so on. Remoting uses serialization "by value" to pass objects between computers or application domains.
2) XML serialization serializes only public properties and fields and does not preserve type fidelity. This is useful when you want to provide or consume data without limiting the applications that use it. Because XML is an open standard, this is a good choice for sharing data through Web. SOAP is also an open standard, which makes it an attractive choice.
3) Serializes and deserializes an instance of a type into an XML stream or document (or JSON format) using the provided data contract. Often used for WCF communication.
BinaryFormatter
Serialization can be defined as the process of storing the state of an object to a storage medium. In this process, the public and private fields of the object and the name of the class (including the assembly that contains the class) are converted to a byte stream, which is then written to the data stream. When the object is deserialized later, an exact copy of the original object is created.
1. The easiest way to make a class serializable is to use the Serializable attribute tag as shown below.
2. Selective serialization
You can prevent member variables from being serialized by marking them with NonSerialized attributes
3. Custom serialization
1) Run custom methods during and after serialization
The best practice and simplest approach (introduced in. Net Framework version 2.0) is to apply the following attributes to methods used to correct data during and after serialization:
OnDeserializedAttribute OnDeserializingAttribute OnSerializedAttribute OnSerializingAttribute
Specific examples are as follows:
// This is the object that will be serialized and deserialized.
[Serializable()]
public class TestSimpleObject
{
// This member is serialized and deserialized with no change.
public int member1;
// The value of this field is set and reset during and
// after serialization.
private string member2;
// This field is not serialized. The OnDeserializedAttribute
// is used to set the member value after serialization.
[NonSerialized()]
public string member3;
// This field is set to null, but populated after deserialization.
private string member4;
// Constructor for the class.
public TestSimpleObject()
{
member1 = 11;
member2 = "Hello World!";
member3 = "This is a nonserialized value";
member4 = null;
}
public void Print()
{
Console.WriteLine("member1 = '{0}'", member1);
Console.WriteLine("member2 = '{0}'", member2);
Console.WriteLine("member3 = '{0}'", member3);
Console.WriteLine("member4 = '{0}'", member4);
}
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context)
{
member2 = "This value went into the data file during serialization.";
}
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context)
{
member2 = "This value was reset after serialization.";
}
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context)
{
member3 = "This value was set during deserialization";
}
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
member4 = "This value was set after deserialization.";
}
}
2) Implement the ISerializable interface
Default serialization should not be used for classes marked with the Serializable attribute that are declaratively or imperative safe at the class level or on its constructor. Instead, these classes should always implement the ISerializable interface. Implementing ISerializable involves implementing GetObjectData methods and special constructors used when deserializing objects.
Specific examples are as follows:
[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");
}
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter
=true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("i", n1);
info.AddValue("j", n2);
info.AddValue("k", str);
}
}
Note:
The constructor is not called when deserializing 1 object. This constraint is imposed on deserialization for performance reasons. However, this violates one of the common conventions between the runtime and object writers, and developers should make sure they understand the consequences when marking objects as serializable.
SoapFormatter
Serializes and deserializes the graph of an object or entire connection object in SOAP format. The basic usage is similar to BinaryFormatter. The SoapFormatter and BinaryFormatter classes implement the IRemotingFormatter interface to support remote procedure calls (RPC) and the IFormatter interface (inherited from IRemotingFormatter) to support serialization of object graphics. The SoapFormatter class also supports RPC on ISoapMessage objects without using the IRemotingFormatter functionality.
XmlSerializer
Serializes objects into and deserializes objects from an XML document. XmlSerializer gives you control over how objects are encoded into XML.
XML serialization is the process of converting the public properties (Property) and fields of an object into sequence format (XML in this case) for storage or transfer. Deserialization is to recreate the object in its original state from the XML output. Therefore, serialization can be regarded as a way to save the state of an object to a stream or buffer. For example, ASP. NET uses the XmlSerializer class to encode an XML Web services message.
Examples:
C # code
public class MyClass
{
public MyObject MyObjectProperty;
}
public class MyObject
{
public string ObjectName;
}
Serialized XML
<MyClass>
<MyObjectProperty>
<ObjectName>My String</ObjectName>
</MyObjectProperty>
</MyClass>
The output of ES 117EN can also be controlled by tags
1. Default value
DefaultValueAttribute
2. Filter an attribute or field
XmlIgnoreAttribute
3. Override the default serialization logic
For details, see: http://msdn.microsoft.com/zh-cn/library/system. xml. serialization. xmlattributeoverrides (v=vs.80). aspx
For other control measures, see http://msdn.microsoft. com/zh-cn/library/83y7df3e (v=vs.80). aspx
4. Serialize the object into an XML stream encoded by SOAP
http://msdn.microsoft.com/zh-cn/library/bd04skah(v=vs.80).aspx
Attention
XML serialization does not transform methods, indexers, private fields, or read-only properties (except read-only collections). To serialize all fields and properties of an object (public and private), use BinaryFormatter instead of XML serialization.
DataContractSerializer
Serializes and deserializes an instance of a type into an XML stream or document using the provided data contract. This class cannot be inherited.
DataContractSerializer is used to serialize and deserialize data sent in an Windows Communication Foundation (WCF) message. By applying the DataContractAttribute attribute (Attribute) to the class and the DataMemberAttribute attribute (Attribute) to the class members, you can specify the attributes (Property) and fields to serialize.
Use steps:
1) DataContractSerializer is used in conjunction with DataContractAttribute and DataMemberAttribute classes.
To prepare to serialize a class, apply DataContractAttribute to the class. For each member of the class that returns the data to be serialized, apply DataMemberAttribute. You can serialize fields and properties regardless of their accessibility level: private, protected, internal, protected, internal, or public.
2) Add to a collection of known types
When serializing or deserializing an object, DataContractSerializer must "know" the type. First, create an implementation of IEnumerable < T > (E. G. List < T > And add a known type to the collection. Then, use the IEnumerable < T > (For example, 1 of the overload of [M: System. Runtime. Serialization. # ctor (System. Type, System. Collections. Generic. IEnumerable {System. Type}]) creates an instance of DataContractSerializer.
Specific examples:
namespace DataContractSerializerExample
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
// You must apply a DataContractAttribute or SerializableAttribute
// to a class to have it serialized by the DataContractSerializer.
[DataContract(Name = "Customer", Namespace = "http://www.contoso.com")]
class Person : IExtensibleDataObject
{
[DataMember()]
public string FirstName;
[DataMember]
public string LastName;
[DataMember()]
public int ID;
public Person(string newfName, string newLName, int newID)
{
FirstName = newfName;
LastName = newLName;
ID = newID;
}
private ExtensionDataObject extensionData_Value;
public ExtensionDataObject ExtensionData
{
get
{
return extensionData_Value;
}
set
{
extensionData_Value = value;
}
}
}
public sealed class Test
{
private Test() { }
public static void Main()
{
try
{
WriteObject("DataContractSerializerExample.xml");
ReadObject("DataContractSerializerExample.xml");
}
catch (SerializationException serExc)
{
Console.WriteLine("Serialization Failed");
Console.WriteLine(serExc.Message);
}
catch (Exception exc)
{
Console.WriteLine(
"The serialization operation failed: {0} StackTrace: {1}",
exc.Message, exc.StackTrace);
}
finally
{
Console.WriteLine("Press <Enter> to exit....");
Console.ReadLine();
}
}
public static void WriteObject(string fileName)
{
Console.WriteLine(
"Creating a Person object and serializing it.");
Person p1 = new Person("Zighetti", "Barbara", 101);
FileStream writer = new FileStream(fileName, FileMode.Create);
DataContractSerializer ser =
new DataContractSerializer(typeof(Person));
ser.WriteObject(writer, p1);
writer.Close();
}
public static void ReadObject(string fileName)
{
Console.WriteLine("Deserializing an instance of the object.");
FileStream fs = new FileStream(fileName,
FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(Person));
// Deserialize the data and read it from the instance.
Person deserializedPerson =
(Person)ser.ReadObject(reader, true);
reader.Close();
fs.Close();
Console.WriteLine(String.Format("{0} {1}, ID: {2}",
deserializedPerson.FirstName, deserializedPerson.LastName,
deserializedPerson.ID));
}
}
DataContractJsonSerializer
Serializes an object into an JavaScript object representation (JSON) and deserializes JSON data into an object. This class cannot be inherited.
The specific use is similar to DataContractSerializer. I won't repeat it here.
The following is a summary of the use of these methods, hoping to bring some help to everyone.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;
namespace SerializerSample
{
/// <summary>
/// Serialization helper class
/// </summary>
public sealed class SerializeHelper
{
#region DataContract Serialization
/// <summary>
/// DataContract Serialization
/// </summary>
/// <param name="value"></param>
/// <param name="knownTypes"></param>
/// <returns></returns>
public static string SerializeDataContract(object value, List<Type> knownTypes = null)
{
DataContractSerializer dataContractSerializer = new DataContractSerializer(value.GetType(), knownTypes);
using (MemoryStream ms = new MemoryStream())
{
dataContractSerializer.WriteObject(ms, value);
ms.Seek(0, SeekOrigin.Begin);
using (StreamReader sr = new StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}
/// <summary>
/// DataContract Deserialization
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml"></param>
/// <returns></returns>
public static T DeserializeDataContract<T>(string xml)
{
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
return (T)serializer.ReadObject(ms);
}
}
#endregion
#region DataContractJson Serialization
/// <summary>
/// DataContractJson Serialization
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string SerializeDataContractJson(object value)
{
DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(value.GetType());
using (MemoryStream ms = new MemoryStream())
{
dataContractSerializer.WriteObject(ms, value);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
/// <summary>
/// DataContractJson Deserialization
/// </summary>
/// <param name="type"></param>
/// <param name="str"></param>
/// <returns></returns>
public static object DeserializeDataContractJson(Type type, string str)
{
DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(type);
using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(str)))
{
return dataContractSerializer.ReadObject(ms);
}
}
/// <summary>
/// DataContractJson Deserialization
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="json"></param>
/// <returns></returns>
public T DeserializeDataContractJson<T>(string json)
{
DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
return (T)dataContractSerializer.ReadObject(ms);
}
}
#endregion
#region XmlSerializer Serialization
/// <summary>
/// Serializes an object to the XML Document and from XML Deserializes an object in a document. XmlSerializer Enables you to control how objects are encoded into XML Medium.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string SerializeXml(object value)
{
XmlSerializer serializer = new XmlSerializer(value.GetType());
using (MemoryStream ms = new MemoryStream())
{
serializer.Serialize(ms, value);
ms.Seek(0, SeekOrigin.Begin);
using (StreamReader sr = new StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}
/// <summary>
/// XmlSerializer Deserialization
/// </summary>
/// <param name="type"></param>
/// <param name="str"></param>
/// <returns></returns>
public static object DeserializeXml(Type type, string str)
{
XmlSerializer serializer = new XmlSerializer(type);
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
using (MemoryStream ms = new MemoryStream(bytes))
{
return serializer.Deserialize(ms);
}
}
#endregion
#region BinaryFormatter Serialization
/// <summary>
/// BinaryFormatter Serialization
/// Must type must be marked as Serializable
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string SerializeBinaryFormatter(object obj)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms,obj);
byte[] bytes = ms.ToArray();
obj = formatter.Deserialize(new MemoryStream(bytes));
// If it is UTF8 Format, deserialization reports an error. Can be used Default Format, however, it is recommended to pass the reference as byte Array is better
return Encoding.Default.GetString(bytes);
}
}
/// <summary>
/// BinaryFormatter Deserialization
/// Must type must be marked as Serializable
/// </summary>
/// <param name="serializedStr"></param>
/// <returns></returns>
public static T DeserializeBinaryFormatter<T>(string serializedStr)
{
BinaryFormatter formatter = new BinaryFormatter();
byte[] bytes = Encoding.Default.GetBytes(serializedStr);
using (MemoryStream ms = new MemoryStream(bytes))
{
return (T)formatter.Deserialize(ms);
}
}
#endregion
#region SoapFormatter Serialization
/// <summary>
/// SoapFormatter Serialization
/// Must type must be marked as Serializable
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string SerializeSoapFormatter(object obj)
{
SoapFormatter formatter = new SoapFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms, obj);
byte[] bytes = ms.ToArray();
return Encoding.UTF8.GetString(bytes);
}
}
/// <summary>
/// SoapFormatter Deserialization
/// Must type must be marked as Serializable
/// </summary>
/// <param name="serializedStr"></param>
/// <returns></returns>
public static T DeserializeSoapFormatter<T>(string serializedStr)
{
SoapFormatter formatter = new SoapFormatter();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serializedStr)))
{
return (T)formatter.Deserialize(ms);
}
}
#endregion
}
}
The specific example code is as follows:
Download: demo