none
序列化,Soap與Binary有什麼限制或差異? RRS feed

  • 問題

  • 物件序列化,Soap與Binary有什麼限制或差異?




    TestClass myTestClass= new TestClass();
    myTestClass.listSomeClass .Add(new SomeClass());
    myTestClass.listSomeClass .Add(new SomeClass());


     SerializeBinaryeObject("myTestClass.xml", myTestClass);

    用Soap 會失敗: Soap 序列化程式不支援一般型別的序列化 : System.Collections.Generic.List`1.....。
    用Binary 會成功





    Class sample
    TestClass.cs
        [Serializable] 
        public class TestClass
        {
            public Guid gid = Guid.NewGuid();
            public double w = 1024d;
            public double h = 768d;
            public string desc = "";
            public List<SomeClass> listSomeClass = new List<SomeClass>();

            public override string ToString()
            {
                return String.Format("{0},{1}X{2},({3})", desc, ((int)this.w).ToString(), ((int)this.h).ToString(), listSomeClass .Count.ToString());
            }

        }

    SomeClass.cs
        [Serializable] 
        public class SomeClass
        {
            public Guid gid = Guid.NewGuid();
            public double w = 1024d;
            public double h = 768d;
            public override string ToString()
            {
                return "";
            }
        }

            public static void SerializeBinaryeObject(String FN, Object o)
    
    
    
            {
    
    
    
                FileStream fs = new FileStream(FN, FileMode.Create);
    
    
    
                BinaryFormatter formatter = new BinaryFormatter();
    
    
    
                //    SoapFormatter formatter = new SoapFormatter();
    
    
    
                try
    
    
    
                {
    
    
    
                    formatter.Serialize(fs, o);
    
    
    
                }
    
    
    
                catch (SerializationException e)
    
    
    
                {
    
    
    
                    Console.WriteLine("Failed to serialize. Reason: " + e.Message);
    
    
    
                    throw;
    
    
    
                }
    
    
    
                finally
    
    
    
                {
    
    
    
                    fs.Close();
    
    
    
                }
    
    
    
            }
    
    
    
            public static Object DeSerializeObject(String FN)
    
    
    
            {
    
    
    
                Object o = null;
    
    
    
                FileStream oFileStream = new FileStream(FN, FileMode.Open);
    
    
    
                //SoapFormatter myBinaryFormatter = new SoapFormatter();
    
    
    
                BinaryFormatter myBinaryFormatter = new BinaryFormatter();
    
    
    
    
    
    
    
                //將檔案還原成原來的物件  
    
    
    
                o = (Object)myBinaryFormatter.Deserialize(oFileStream);
    
    
    
                return o;
    
    
    
            }
    
    
    
    
    • 已編輯 HikaruGo 2010年1月13日 上午 07:12
    2010年1月13日 上午 06:54

解答

  • 如果要用dotNet內建的自動序列化 (使用[Serializable]),前提是要序列化的類別中的成員變數或屬性都能序列化.
    而大多數dotNet內建型別本身都能序列化但你的程式中有 List<SomeClass> listSomeClass所以SomeClass如不支援序列化,則TestClass也無法序列化.
    而你的問題在於List<>這個泛型型別並不支援SOAP模式的序列化(如同錯誤訊息所描述),故你可能要用其他方式處理.譬如將 List<>改用ArrayList等型別.
    或比較符合需求但較複雜的做法,自行手動處理List<>該如何序列化為SOAP格式,作法參考
    http://msdn.microsoft.com/zh-tw/library/system.runtime.serialization.formatters.soap.soapformatter(VS.80).aspx
    • 已標示為解答 Lolota Lee 2010年1月19日 上午 06:02
    2010年1月13日 上午 07:52
  • hi,
    前陣子剛好看書整理了一些筆記,希望派的上用場XD

    http://www.dotblogs.com.tw/alonstar/archive/2009/12/02/12252.aspx

    My Blog:http://www.dotblogs.com.tw/alonstar
    解決問題之後,別忘了回到論壇把正確回應標示成解答哦!
    • 已標示為解答 Lolota Lee 2010年1月19日 上午 06:02
    2010年1月13日 上午 08:42

所有回覆

  • 序列化的目的在於讓兩個程式間的資料,能夠用一種雙方都能看得懂的方式做傳遞.
    所以要決定用哪種模式做為序列化的資料結構, 端看雙方都能夠看得懂的型式來決定.
    舉例來說
    ASP.Net中常用ViewState來儲存資料,而ViewState是使用HTML中的Hidden作為實現方式,而Hidden必須存在於HTML中,故如果需要將類別儲存在ViewState就必須將類別資料序列化為字串型態,故可以選擇XML或SOAP等形式,而Binary就不可行(除非再做一次轉換).

    大多數的情況
    Binary比起其他格式的資料來得小,有利於傳遞上較為快速,但相對的Binary並無法用於大多數的情況,而 SOAP與XML這類文字型式的結構剛好相反.
    故要採用哪種方式就必須依情況來決定.
    2010年1月13日 上午 07:08
  • 序列化的目的在於讓兩個程式間的資料,能夠用一種雙方都能看得懂的方式做傳遞.
    所以要決定用哪種模式做為序列化的資料結構, 端看雙方都能夠看得懂的型式來決定.
    舉例來說


    我將資料序列化就出錯了

    TestClass myTestClass= new TestClass();
     SerializeBinaryeObject("myTestClass.xml", myTestClass);  


    用Soap 會失敗: Soap 序列化程式不支援一般型別的序列化 : System.Collections.Generic.List`1.....。
    用Binary 會成功
    2010年1月13日 上午 07:33
  • 如果要用dotNet內建的自動序列化 (使用[Serializable]),前提是要序列化的類別中的成員變數或屬性都能序列化.
    而大多數dotNet內建型別本身都能序列化但你的程式中有 List<SomeClass> listSomeClass所以SomeClass如不支援序列化,則TestClass也無法序列化.
    而你的問題在於List<>這個泛型型別並不支援SOAP模式的序列化(如同錯誤訊息所描述),故你可能要用其他方式處理.譬如將 List<>改用ArrayList等型別.
    或比較符合需求但較複雜的做法,自行手動處理List<>該如何序列化為SOAP格式,作法參考
    http://msdn.microsoft.com/zh-tw/library/system.runtime.serialization.formatters.soap.soapformatter(VS.80).aspx
    • 已標示為解答 Lolota Lee 2010年1月19日 上午 06:02
    2010年1月13日 上午 07:52
  • hi,
    前陣子剛好看書整理了一些筆記,希望派的上用場XD

    http://www.dotblogs.com.tw/alonstar/archive/2009/12/02/12252.aspx

    My Blog:http://www.dotblogs.com.tw/alonstar
    解決問題之後,別忘了回到論壇把正確回應標示成解答哦!
    • 已標示為解答 Lolota Lee 2010年1月19日 上午 06:02
    2010年1月13日 上午 08:42