天天看點

Webservice SOAP傳輸序列化總結

一.所有Webservice中傳遞的對象都必須能夠序列化,這個是作為在網絡之間傳輸的必要條件。XML WebService和SOAP标準支援的資料類型如下: 

  1.基本資料類型.  

      标準類型,如:int float bool DateTime string等基本資料類型 

  2.枚舉. 

      支援枚舉Enum定義的類型 

  3.自定義對象. 

      可以傳遞任意基于自定義類或結建構立的對象。 但要注意一點: 它隻能傳輸資料成員(變量和屬性). 

      如果定義了方法,則方法不能進行序列化傳輸,序列化後隻剩下資料成員. 

  4.DataSet對象 

      支援DataSet,切記:不支援DataTable和DataRow,DataSet已經是XML Webservice能夠支援的最小的可序列化對象. 

  5.XmlNode對象 

      基于XmlNode的對象可以表示XML文檔的一部分. 

  6.數組和集合 

      可以使用任何被支援的類型的數組和簡單集合,包括: DataSet對象/XmlNode對象和自定義對象. 

不知道讀者有沒有遇到這種情況,在調用WebService并給一個方法傳遞了一個DataRow參數時,運作時會抛出異常: "沒法将參數序列化!",如果把DataRow加入到DataSet中,并将DataSet作為參數傳遞再運作就OK了。 這是因為:XML WebService隻能對資料集DataSet對象類型進行XML序列化,不能對DataRow對象類型進行XML序列化造成的錯誤.是以了解一下XML WebService支援序列化的基本資料類型是比較重要的.

除了上述的基本類型以為,Webservice服務不能完成直接序列化傳輸,但是大部分資料結構借助序列化,仍然可以在Webservice上傳輸。

例如:

在将一個自定義類序列化到檔案時,出現如下錯誤提示:

System.Reflection.TargetInvocationException: 調用的目标發生了異常。 ---> 

System.InvalidOperationException: 生成 XML 文檔時出錯。 ---> System.InvalidOperationException: 

不應是類型 Alink.T1System.Windows.PrintSetting。使用 XmlInclude 或 SoapInclude 屬性靜态指定非已知的類型。

經查找資料,發現當被序例化的類中包含自定義的複雜類時,需要使用XmlIncludeAttribut屬性辨別自定義類

現在修改如下:

using System.Xml.Serialization;

[XmlInclude(typeof(自定義類))]

[Serializable]

public class MyDIYClass

自定義的類都添加标記,提供的webservice方法也加标記

[WebMethod]

public object WebServiceMethod(Object requestObj)

要把該類中内含的自定義類都用XmlInclude一次,就可以解決問題了;

這樣就可以傳輸了,List<>,ArrayList對象都可以傳輸,但是傳回類型為ArrayList的[WebMethod]方法,在用戶端調用後,得到的是object數組,而且object中的property全部都變為field。另外,接口也不能序列化例如List<Interface>也是不能序列化的,遇到這種情況可以把接口修改為抽象類,同時在抽象類上添加[XmlInclude]屬性,最後需要注意一點,自己寫的類要想序列化必須有預設構造函數(不帶參數的構造函數)。

xml序列化答疑:

    (1)需序列化的字段必須是公共的(public)

    (2)需要序列化的類都必須有一個無參的構造函數

    (3)枚舉變量可序列化為字元串,無需用[XmlInclude]

    (4)導出非基本類型對象,都必須用[XmlInclude]事先聲明。該規則遞歸作用到子元素

        如導出ArrayList對象,若其成員是自定義的,需預包含處理:

        using System.Xml.Serialization;

        [XmlInclude(typeof(自定義類))]

    (5)Attribute中的IsNullable參數若等于false,表示若元素為null則不顯示該元素。

        也就是說:針對值類型(如結構體)該功能是實效的

        若數組包含了100個空間,填充了10個類對象,則序列化後隻顯示10個節點

        若數組包含了100個空間,填充了10個結構體對象,則序列化後會顯示100個節點

    (6)真正無法XML序列化的情況,某些類就是無法XML序列化的(即使使用了[XmlInclude])

            IDictionary(如HashTable)

            System.Drawing.Color

            System.Drawing.Font

            SecurityAttribute聲明

            父類對象賦予子類對象值的情況

            對象間循環引用