c serialization detail example

  • 2020-06-12 10:32:06
  • OfStack


Several serialization techniques:
1) Base 2 serialization maintains type fidelity, which is useful for preserving the state of objects between calls to the application. For example, objects can be Shared between different applications by serializing them to the clipboard. You can serialize objects to streams, disks, memory, networks, and so on. Remote processing USES serialization "by value" to pass objects between computers or application domains.
2) XML serialization serializes only public properties and fields and does not maintain type fidelity. This is useful when you want to provide or use data without restricting the applications that use it. Since 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 option.
3) Serialize and deserialize type instances into XML streams or documents (or JSON format) using the data protocols provided. It is often used in WCF communication.

BinaryFormatter

Serialization can be defined as the process of storing the state of an object into a storage medium. In this process, the public and private fields of the object and the name of the class (including the assembly containing the class) are converted to a byte stream and then written to the data stream. When the object is later deserialized, 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

Member variables can be prevented from being serialized by marking them with the NonSerialized attribute

3. Custom serialization

1) Run custom methods during and after serialization
The best practice, which was introduced with.Net Framework 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 ISerializable interface

Default serialization should not be used for classes marked with the Serializable attribute that are either declarative or imperative secure at the class level or its constructor. Instead, these classes should always implement the ISerializable interface. Implementing ISerializable involves implementing the GetObjectData methods and special constructors to use 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:

No constructor is called when deserializing an object. This constraint is imposed on deserialization for performance reasons. However, this violates one of the common conventions between the runtime and the object writer, and developers should make sure they understand the consequences when marking objects as serializable.

SoapFormatter

Serialize and deserialize graphs of objects or entire connection objects 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 by IRemotingFormatter) to support serialization of object graphics. The SoapFormatter class also supports RPC objects without using the IRemotingFormatter functionality.

XmlSerializer

Serialize objects into and out of the XML document. XmlSerializer gives you control over how objects are encoded into XML.

XML serialization is the process of converting the common properties (Property) and fields of an object into sequence format (XML in this case) for storage or transport. Deserialization recreates the original state of the object from the XML output. Therefore, you can think of serialization as a way of saving the state of an object to a stream or buffer. For example, ES90en.NET USES the XmlSerializer class to encode XML Web services messages.

Example:

C # code


public class MyClass
{
    public MyObject MyObjectProperty;
}
public class MyObject
{
    public string ObjectName;
}

Serialized XML


<MyClass>
  <MyObjectProperty>
  <ObjectName>My String</ObjectName>
  </MyObjectProperty>
</MyClass>

You can also control the output of XML through tags

1. Default values

DefaultValueAttribute

2. Filter a property or field

XmlIgnoreAttribute

3. Override the default serialization logic
4. Serialize the object to XML stream encoded by SOAP

Pay attention to

XML serialization does not transform methods, indexers, private fields, or read-only properties (except for read-only collections). To serialize all fields and properties of the object (public and private), use BinaryFormatter instead of XML serialization.

DataContractSerializer

Serialize and deserialize type instances into XML streams or documents using the data protocols provided. This class cannot be inherited.

DataContractSerializer is used to serialize and deserialize data sent in Windows Communication Foundation (WCF) messages. By applying the DataContractAttribute attribute (Attribute) to a class and the DataMemberAttribute attribute (Attribute) to a class member, you can specify which attributes (Property) and fields to serialize.

Steps:

1) DataContractSerializer is used in combination with DataContractAttribute and DataMemberAttribute.

To prepare a class for serialization, apply DataContractAttribute to that class. Apply DataMemberAttribute for each member of the class that returns the data to be serialized. 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 > (such as List < T > ) and adds a known type to the collection. Then, use accept IEnumerable < T > (for example, [M: System. Runtime. Serialization. DataContractSerializer. # ctor (System. Type, System. Collections. Generic. IEnumerable {System. Type}]) 1 create DataContractSerializer instances of overloading.

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

Serialize the object to the JavaScript object representation (JSON) and deserialize the JSON data to the object. This class cannot be inherited.

Specific use is similar to DataContractSerializer. It will not be repeated here.

The following is a summary of the use of these methods, I hope to give you 1 help.


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>
    ///  Serialized 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>
  ///  Serialize the object to  XML  Document and from  XML  Deserialize objects in a document. XmlSerializer  Gives you control over how objects are coded to  XML  In the. 
  /// </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 
  ///  The 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, then deserialize error. You can use Default Format, however, it is recommended to pass the reference as byte Arrays are better 
    return Encoding.Default.GetString(bytes);
}
  }
  /// <summary>
  /// BinaryFormatter deserialization 
  ///  The 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 
  ///  The 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 
  ///  The 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
    }
}


Related articles: