分析問題

  為了序列化具體實例到某種專業的格式,.NET提供了三種對象序列格式化類型:BinaryFormatter、SoapFormatter和XmlSerializer。

  BinaryFormatter用於將可序列化的對象序列化成二進制的字節流,而SoapFormatter則致力於把可序列化的類型序列化成符合SOAP規範的XML文檔,以供使用。對於那些使用Serializable特性來申明成可序列化類型的對象,BinaryFormatter和SoapFormatter可以方便地把它們序列化成特定的格式。

説明

  SOAP是一種位於應用層的網絡協議,它基於XML,並且是Web服務的基本協議,後續章節將覆蓋關於SOAP的面試題。

  另外,.NET提供了一個執行序列化操作的類型XmlSerializer。不同於BinaryFormatter和SoapFormatter,XmlSerializer並不針對那些使用Serializable特性的類型,事實上,Serializable和NonSerialized特性在XmlSerializer類型對象的操作中完全不起作用,取而代之的是XmlIgnore屬性。XmlSerializer可以對沒有Serializable特性修飾的類型對象進行序列化,但它仍然有一定的限制:

  1、使用XmlSerializer序列化的對象類型必須顯式地擁有一個無參的公共構造方法。

  2、XmlSerializer只能序列化公共成員變量。

  以下代碼展示了SoapFormatter和XmlSerializer類型的使用方法,首先為了演示起見,定義一個將被用來測試序列化的簡單類型。

using System;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;



namespace Test111
{
    class DoSerialize
    {
        static void Main()
        {
            MyObject obj = new MyObject(10, "我是字符串");
            Console.WriteLine("原始對象是:");
            Console.WriteLine(obj);
            //使用SoapFormatter進行序列化
            byte[] data = SoapFormatterSerialize(obj);
            Console.WriteLine("SoapFormatter序列化後:{0}\r\n",Encoding.UTF8.GetString(data));
            //使用XmlSerializer進行序列化
            byte[] data1 = XmlSerializerSerialize(obj);
            Console.WriteLine("XmlSerializer序列化後:{0}\r\n", Encoding.UTF8.GetString(data1));
            Console.Read();
        }

        //SoapFormatter序列化
        static byte[] SoapFormatterSerialize(MyObject obj)
        {
            using (MemoryStream ms=new MemoryStream ())
            {
                SoapFormatter sf = new SoapFormatter();
                sf.Serialize(ms, obj);
                return ms.ToArray();
            }
        }

        //SoapFormatter反序列化
        static MyObject SoapFormatterDeSerialize(byte[] bytes)
        {
            using (MemoryStream ms=new MemoryStream (bytes))
            {
                SoapFormatter sf = new SoapFormatter();
                return sf.Deserialize(ms) as MyObject;
            }
        }

        //使用XmlSerializer序列化
        static byte[] XmlSerializerSerialize(MyObject obj)
        {
            using (MemoryStream ms = new MemoryStream ())
            {
                XmlSerializer xs = new XmlSerializer(typeof(MyObject));
                xs.Serialize(ms, obj);
                return ms.ToArray();
            }
        }

        //使用XmlSerializer反序列化
        static MyObject XmlSerializerDeSerialize(byte[] bytes)
        {
            using (MemoryStream ms=new MemoryStream (bytes))
            {
                XmlSerializer xs = new XmlSerializer(typeof(MyObject));
                return xs.Deserialize(ms) as MyObject;
            }
        }

    }

    [Serializable]
    public class MyObject
    { 
        //私有成員,不能被XmlSerializer序列化
        private int _myInt;

        //申明不可被序列化
        [NonSerialized]
        public string _myString1;

        //申明不可被XmlSerializer序列化
        [XmlIgnore]
        public string _myString2;

        public MyObject() 
        {
            _myInt = 0;
            _myString1 = string.Empty;
            _myString2 = string.Empty;
        }

        public MyObject(int i, string s)
        {
            _myInt = i;
            _myString1 = s;
            _myString2 = s;
        }

        public override string ToString()
        {
            return new StringBuilder().AppendFormat("整數是:{0}\r\n字符串1是:{1}\r\n字符串2是:{2}",_myInt.ToString(),_myString1,_myString2).ToString();
        }

    }
}

  

使用IIS 將 SOAP服務 轉換成 REST 服務_System

 

答案

  .NET內建類型提供了三個可執行序列化和反序列化操作的類型:BinaryFormatter、SoapFormatter和XmlSerializer。BinaryFormatter和SoapFormatter可以對那些有Serializable特性的類型進行序列化和反序列化操作,除了由NonSerialized特性修飾的成員,兩者將序列化所有其他的成員。而XmlSerializer不需要對對象類型申明Serializable特性,但它要求對象類型有一個顯式的無參公共構造方法,並且它不能序列化對象的非公共成員和由XmlIgnore修飾的成員。