.net 系列化與反序列化(轉載)

.net序列化及反序列化

轉載自:http://www.cnblogs.com/Tim_Liu/archive/2010/11/09/1872587.htmlhtml

 

序列化是指一個對象的實例能夠被保存,保存成一個二進制串,固然,一旦被保存成二進制串,那麼也能夠保存成文本串了。
好比,一個計數器,數值爲2,咱們能夠用字符串「2」表示。
若是有個對象,叫作connter,當前值爲2,那麼能夠序列化成「2」,反向的,也能夠從「2」獲得值爲2的計數器實例。
這樣,關機時序列化它,開機時反序列化它,每次開機都是延續的。不會都是從頭開始。web

序列化概念的提出和實現,可使咱們的應用程序的設置信息保存和讀取更加方便。編程

序列化有不少好處,好比,在一臺機器上產生一個實例,初始化完畢,而後能夠序列化,經過網絡傳送到另外一臺機器,而後反序列化,獲得對象實例,以後再執行某些業務邏輯,獲得結果,再序列化,返回第一臺機器,第一臺機器獲得對象實例,獲得結果。
這個例子是目前比較先進的「智能代理」的原理。api

當前比較熱火的web services使用soap協議,soap協議也是以對象的可序列化爲基礎的。數組

一 概述
.NET Framework爲處理XML數據提供了許多不一樣的類庫。XmlDocument類能讓你像處理文件同樣處理xml數據,而XmlReader、XmlWriter和它們的派生類使你可以將xml數據做爲數據流處理。
XmlSerializer則提供了另外的方法,它使你可以將本身的對象串行化和反串行化爲xml。串行化數據既可以讓你像處理文件同樣對數據進行隨機處理,同時又能跳過你不感興趣的數據。
二 主要類庫介紹
   .NET 支持對象xml序列化和反序列化的類庫主要位於命名空間System.Xml.Serialization中。
   1.  XmlSerializer 類
   該類用一種高度鬆散耦合的方式提供串行化服務。你的類不須要繼承特別的基類,並且它們也不須要實現特別的接 口。相反,你只需在你的類或者這些類的公共域以及讀/寫屬性里加上自定義的特性。XmlSerializer經過反射機制讀取這些特性並用它們將你的類和 類成員映射到xml元素和屬性。
   2. XmlAttributeAttribute 類
   指定類的公共域或讀/寫屬性對應xml文件的Attribute。
   例:[XmlAttribute(「type」)] or [XmlAttribute(AttributeName=」type」)]
   3. XmlElementAttribute類
   指定類的公共域或讀/寫屬性對應xml文件的Element。
   例:[XmlElement(「Maufacturer」)] or [XmlElement(ElementName=」Manufacturer」)]
   4. XmlRootAttribute類
   Xml序列化時,由該特性指定的元素將被序列化成xml的根元素。
   例:[XmlRoot(「RootElement」)] or [XmlRoot(ElementName = 「RootElements」)]
   5. XmlTextAttribute 類
   Xml序列化時,由該特性指定的元素值將被序列化成xml元素的值。一個類只容許擁有一個該特性類的實例,由於xml元素只能有一個值。
   6. XmlIgnoreAttribute類
   Xml序列化時不會序列化該特性指定的元素。
三 實例
   下面例子中的xml schema 描述了一個簡單的人力資源信息,其中包含了xml的大部分格式,如xml 元素相互嵌套, xml元素既有元素值,又有屬性值。
   1. 待序列化的類層次結構
    [XmlRoot("humanResource")]
    public class HumanResource
    {
        #region private data.
        private int m_record = 0;
        private Worker[] m_workers = null;
        #endregion
 
        [XmlAttribute(AttributeName="record")]
        public int Record
        {
            get { return m_record; }
            set { m_record = value; }
        }
 
        [XmlElement(ElementName="worker")]
        public Worker[] Workers
        {
            get { return m_workers; }
            set { m_workers = value; }
        }
}
 
    public class Worker
    {
        #region private data.
        private string m_number = null;
        private InformationItem[] m_infoItems = null;
        #endregion
 
        [XmlAttribute("number")]
        public string Number
        {
            get { return m_number; }
            set { m_number = value; }
        }
 
        [XmlElement("infoItem")]
        public InformationItem[] InfoItems
        {
            get { return m_infoItems; }
            set { m_infoItems = value; }
        }
}
 
    public class InformationItem
    {
        #region private data.
        private string m_name = null;
        private string m_value = null;
        #endregion
 
        [XmlAttribute(AttributeName = "name")]
        public string Name
        {
            get { return m_name; }
            set { m_name = value; }
        }
 
        [XmlText]
        public string Value
        {
            get { return m_value; }
            set { m_value = value; }
        }
}
   2. 序列化生成的xml結構
       <?xml version="1.0" ?>
- <humanResource xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=" http://www.w3.org/2001/XMLSchema" record=" 2">
- <worker number=" 001">
                 <infoItem name=" name"> Michale</infoItem>
                 <infoItem name=" sex"> male</infoItem>
                 <infoItem name=" age"> 25</infoItem>
            </worker>
- <worker number=" 002">
                 <infoItem name=" name"> Surce</infoItem>
                 <infoItem name=" sex"> male</infoItem>
                 <infoItem name=" age"> 28</infoItem>
           </worker>
         </humanResource>
   3. 利用XmlSerializer類進行序列化和反序列化的實現(通常利用緩存機制實現xml文件只解析一次。)
    public sealed class ConfigurationManager
    {
        private static HumanResource m_humanResource = null;
        private ConfigurationManager(){}
 
        public static HumanResource Get(string path)
        {
            if (m_humanResource == null)
            {
                FileStream fs = null;
                try
                {
                    XmlSerializer xs = new XmlSerializer(typeof(HumanResource));
                    fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                    m_humanResource = (HumanResource)xs.Deserialize(fs);
                    fs.Close();
                    return m_humanResource;
                }
                catch
                {
                    if (fs != null)
                        fs.Close();
                    throw new Exception("Xml deserialization failed!");
                }
 
            }
            else
            {
                return m_humanResource;
            }
        }
 
        public static void Set(string path, HumanResource humanResource)
        {
            if (humanResource == null)
                throw new Exception("Parameter humanResource is null!");
           
            FileStream fs = null;
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(HumanResource));
                fs = new FileStream(path, FileMode.Create, FileAccess.Write);
                xs.Serialize(fs, humanResource);
                m_humanResource = null;
                fs.Close();
            }
            catch
            {
                if (fs != null)
                    fs.Close();
                throw new Exception("Xml serialization failed!");
            }
        }
    }
四 說明
   1. 須要序列化爲xml元素的屬性必須爲讀/寫屬性;
   2. 注意爲類成員設定缺省值,儘管這並非必須的。

    「序列化」可被定義爲將對象的狀態存儲到存儲媒介中的過程。在此過程當中,對象的公共字段和私有字段以及類的名稱(包括包含該類的程序集)都被轉換爲字節流,而後寫入數據流。在之後「反序列化」該對象時,建立原始對象的精確複本。
1、爲何要選擇序列化
    一個緣由是將對象的狀態保持在存儲媒體中,以即可以在之後從新建立精確的副本
    另外一個緣由是經過值將對象從一個應用程序域發送到另外一個應用程序域中
    例如,序列化可用於在 ASP.NET 中保存會話狀態並將對象複製到 Windows 窗體的剪貼板中。遠程處理還可使用序列化經過值將對象從一個應用程序域傳遞到另外一個應用程序域中。
2、如何實現對象的序列化及反序列化
    要實現對象的序列化,首先要保證該對象能夠序列化。並且,序列化只是將對象的屬性進行有效的保存,對於對象的一些方法則沒法實現序列化的。
    實現一個類可序列化的最簡便的方法就是增長Serializable屬性標記類。如:
    [Serializable()]
    public class MEABlock
    {
        private int m_ID;
        public string Caption;緩存

        public MEABlock()
        {
            ///構造函數
        }
    }
    便可實現該類的可序列化。
    要將該類的實例序列化爲到文件中?.NET FrameWork提供了兩種方法:
    一、XML序列化
        使用 XmLSerializer 類,可將下列項序列化。 安全

  • 公共類的公共讀/寫屬性和字段
  • 實現 ICollectionIEnumerable 的類。(注意只有集合會被序列化,而公共屬性卻不會。)
  • XmlElement 對象。
  • XmlNode 對象。
  • DataSet 對象。

         要實現上述類的實例的序列化,可參照以下例子:
        MEABlock myBlock = new MEABlock();
        // Insert code to set properties and fields of the object.
        XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
        // To write to a file, create a StreamWriter object.
        StreamWriter myWriter = new StreamWriter("myFileName.xml");
        mySerializer.Serialize(myWriter, MEABlock);
    須要注意的是XML序列化只會將public的字段保存,對於私有字段不予於保存。
    生成的XML文件格式以下:
        <MEABlock>
            <Caption>Test</Caption>
        </MEABlock>
    對於對象的反序列化,則以下:
        MEABlock myBlock;
        // Constructs an instance of the XmlSerializer with the type
        // of object that is being deserialized.
        XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
        // To read the file, creates a FileStream.
        FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open);
        // Calls the Deserialize method and casts to the object type.
        myBlock = (MEABlock)mySerializer.Deserialize(myFileStream)
    二、二進制序列化
        與XML序列化不一樣的是,二進制序列化能夠將類的實例中全部字段(包括私有和公有)都進行序列化操做。這就更方便、更準確的還原了對象的副本。
        要實現上述類的實例的序列化,可參照以下例子:
        MEABlock myBlock = new MEABlock();
        // Insert code to set properties and fields of the object.
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream("MyFile.bin",FileMode.Create,FileAccess.Write, FileShare.None);
        formatter.Serialize(stream, myBlock);
        stream.Close();
    對於對象的反序列化,則以下:
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream("MyFile.bin", FileMode.Open,FileAccess.Read, FileShare.Read);
        MEABlock myBlock = (MEABlock) formatter.Deserialize(stream);
        stream.Close();

3、如何變相實現自定義可視化控件的序列化、反序列化
        對於WinForm中自定義控件,因爲繼承於System.Windows.Form類,而Form類又是從MarshalByRefObject繼承的,窗體自己沒法作到序列化,窗體的實現基於Win32下GUI資源,不能脫離當前上下文存在。
        固然能夠採用變通的方法實現控件的序列化。這裏採用的是記憶類模型
        定義記憶類(其實就是一個可序列化的實體類)用於記錄控件的有效屬性,須要序列化控件的時候,只須要將該控件的實例Copy到記憶類,演變成序列化保存該記憶類的操做。
        反序列化是一個逆過程。將數據流反序列化成爲該記憶類,再根據該記憶類的屬性生成控件實例。而對於控件的一些事件、方法則能夠繼續使用。服務器

 
.NET Framework 開發員指南  
序列化是將對象轉換爲容易傳輸的格式的過程。例如,能夠序列化一個對象,而後使用 HTTP 經過 Internet 在客戶端和服務器之間傳輸該對象。在另外一端,反序列化將從該流從新構造對象。

XML 序列化僅將對象的公共字段和屬性值序列化爲 XML 流。XML 序列化不包括類型信息。例如,若是您有一個存在於 Library 命名空間中的 Book 對象,將不能保證它將會被反序列化爲同一類型的對象。網絡

注意   XML 序列化不轉換方法、索引器、私有字段或只讀屬性(只讀集合除外)。若要序列化對象的全部字段和屬性(公共的和私有的),請使用 BinaryFormatter,而不要使用 XML 序列化。

XML 序列化中最主要的類是 XmlSerializer 類,它的最重要的方法是 SerializeDeserialize 方法。XmlSerializer 生成的 XML 流符合萬維網聯合會 (www.w3.org) XML 架構定義語言 (XSD) 1.0 的建議。另外,生成的數據類型符合標題爲「XML Schema Part 2: Datatypes」(XML 架構第二部分:數據類型)的文檔。架構

對象中的數據是用編程語言構造(如類、字段、屬性、基元類型、數組,甚至 XmlElementXmlAttribute 對象形式的嵌入 XML)來描述的。您能夠建立本身的用屬性批註的類,或者使用 XML 架構定義工具生成基於現有 XML 架構的類。

若是您有 XML 架構,就可運行 XML 架構定義工具生成一組強類型化爲架構並用屬性批註的類。當序列化這樣的類的實例時,生成的 XML 符合 XML 架構。使用這樣的類,就可針對容易操做的對象模型進行編程,同時確保生成的 XML 符合 XML 架構。這是使用 .NET Framework 中的其餘類(如 XmlReaderXmlWriter 類)分析和寫 XML 流的一種替換方法。(有關使用這些類的更多信息,請參見使用 .NET Framework 中的 XML。)這些類使您能夠分析任何 XML 流。與此相反,當須要 XML 流符合已知的 XML 架構時,請使用 XmlSerializer

屬性控制由 XmlSerializer 類生成的 XML 流,使您能夠設置 XML 流的 XML 命名空間、元素名、屬性名等。有關這些屬性和它們如何控制 XML 序列化的更多信息,請參見使用屬性控制 XML 序列化。若想得到一個列示對所生成的 XML 起控制做用的那些屬性的表,請參見控制 XML 序列化的屬性

XmlSerializer 類可進一步序列化對象並生成編碼的 SOAP XML 流。生成的 XML 符合標題爲「Simple Object Access Protocol (SOAP) 1.1」的萬維網聯合會文檔的第 5 節。有關此過程的更多信息,請參見用 XML 序列化生成 SOAP 消息。有關控制生成的 XML 的屬性表,請參見控制編碼的 SOAP 序列化的屬性

XmlSerializer 類生成由 XML Web services 建立和傳遞給 XML Web services 的 SOAP 消息。若要控制 SOAP 消息,可將屬性應用於 XML Web services 文件 (.asmx) 中的類、返回值、參數和字段。您能夠同時使用在「控制 XML 序列化的屬性」中列出的屬性和在「控制編碼的 SOAP 序列化的屬性」中列出的屬性,由於 XML Web services 可使用文本樣式,也可使用編碼的 SOAP 樣式。有關使用屬性控制 XML Web services 所生成的 XML 的更多信息,請參見 XML Web services 的 XML 序列化。有關 SOAP 和 XML Web services 的更多信息,請參見自定義 SOAP 消息

保護 XmlSerializer 應用程序

在建立使用 XmlSerializer 的應用程序時,您應當瞭解如下幾點以及它們的影響:

  • XmlSerializer 建立 C# 文件 (.cs 文件),並將其編譯成 .dll 文件,這些 .dll 文件位於由 TEMP 環境變量指定的目錄中;這些 DLL 文件將發生序列化。

    代碼和 DLL 在建立和進行編譯時,易於遭受惡意進程的攻擊。若是所使用的計算機運行的是 Microsoft Windows NT 4.0 或更高版本,則有可能會有兩個或更多用戶共享臨時目錄。若是同時存在如下兩種狀況,則共享臨時目錄是有危險性的:(1) 兩個賬戶有不一樣的安全特權;(2) 具備較高特權的賬戶運行一個使用 XmlSerializer 的應用程序。在這種狀況下,某一用戶能夠替換所編譯的 .cs 或 .dll 文件,由此破壞計算機的安全性。爲了不發生這一問題,請始終確保計算機上的每一賬戶都有本身的配置文件。若是可以保證這一點的話,默認狀況下,TEMP 環境變量就會爲不一樣的賬戶指定不一樣的目錄。

  • 若是一名惡意用戶向 Web 服務器發送持續的 XML 數據流(拒絕服務攻擊),XmlSerializer 會一直處理這一數據,直到計算機資源不夠用才中止。

    若是您所使用的計算機運行 Internet 信息服務 (IIS),而且您的應用程序是在 IIS 下運行,就能夠避免這類攻擊。IIS 帶有一個控制門,用於禁止處理大於設定數量(默認值是 4 KB)的數據流。若是您所建立的應用程序不使用 IIS,同時該應用程序使用 XmlSerializer 進行反序列化,則應該實現一個相似的控制門,以阻止拒絕服務攻擊。

  • XmlSerializer 將使用給予它的任何類型,對數據進行序列化,並運行任何代碼。

    惡意對象施加威脅的方式有兩種。一種是運行惡意代碼,另外一種是將惡意代碼插入到由 XmlSerializer 建立的 C# 文件中。在第一種狀況下,若是惡意對象試圖運行破壞性過程,代碼訪問安全性將幫助防止發生任何破壞。在第二種狀況下,在理論上,惡意對象有可能會以某種方式將代碼插入到由 XmlSerializer 建立的 C# 文件中。儘管對這一問題已進行了完全的檢驗,並且這類攻擊被認爲是不可能的,但您仍是應該當心一些,必定不要序列化那些不可信的未知類型的數據。

  • 已序列化的重要數據可能易於遭到攻擊。

    XmlSerializer 對數據進行了序列化以後,數據能夠被存儲爲 XML 文件,或存儲在其餘數據存儲區。若是其餘進程能夠訪問到您的數據存儲區,或是能夠在 Intranet 或 Internet 上看到該數據存儲區,數據就可能被竊取,並被惡意使用。例如,若是您建立了一個應用程序,對包含信用卡號碼的訂單進行序列化,這一數據就很是重要。爲了防 止發生這一問題,請始終保護您的數據存儲區,並對數據採起保密措施。

簡單類的序列化

下面的示例顯示一個具備公共字段的簡單類:

[Visual Basic]Public Class OrderForm    Public OrderDate As DateTimeEnd Class[C#]public class OrderForm{ public DateTime OrderDate;}

當將此類的實例序列化時,該實例可能相似於下面的代碼:

<OrderForm>    <OrderDate>12/12/01</OrderDate></OrderForm>

有關序列化的更多示例,請參見 XML 序列化的示例

能夠序列化的項

使用 XmLSerializer 類,可將下列項序列化。

  • 公共類的公共讀/寫屬性和字段
  • 實現 ICollectionIEnumerable 的類。(注意只有集合會被序列化,而公共屬性卻不會。)
  • XmlElement 對象。
  • XmlNode 對象。
  • DataSet 對象。

序列化和反序列化對象

若要序列化對象,首先建立要序列化的對象並設置它的公共屬性和字段。爲此,必須肯定要用以存儲 XML 流的傳輸格式(或者做爲流,或者做爲文件)。例如,若是 XML 流必須以永久形式保存,則建立 FileStream 對象。當您反序列化對象時,傳輸格式肯定您將建立流仍是文件對象。肯定了傳輸格式以後,就能夠根據須要調用 SerializeDeserialize 方法。

序列化對象

  1. 建立對象並設置它的公共字段和屬性。
  2. 使用該對象的類型構造 XmlSerializer。有關更多信息,請參見 XmlSerializer 類構造函數。
  3. 調用 Serialize 方法以生成對象的公共屬性和字段的 XML 流表示形式或文件表示形式。下面的示例建立一個文件。
    [Visual Basic]Dim myObject As MySerializableClass = New MySerializableClass()' Insert code to set properties and fields of the object.Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))' To write to a file, create a StreamWriter object.Dim myWriter As StreamWriter = New StreamWriter("myFileName.xml")mySerializer.Serialize(myWriter, myObject)[C#]MySerializableClass myObject = new MySerializableClass();// Insert code to set properties and fields of the object.XmlSerializer mySerializer = new XmlSerializer(typeof(MySerializableClass));// To write to a file, create a StreamWriter object.StreamWriter myWriter = new StreamWriter("myFileName.xml");mySerializer.Serialize(myWriter, myObject);

反序列化對象

  1. 使用要反序列化的對象的類型構造 XmlSerializer
  2. 調用 Deserialize 方法以產生該對象的副本。在反序列化時,必須將返回的對象強制轉換爲原始對象的類型,以下面的示例中所示。下面的示例將該對象反序列化爲文件,儘管它也能夠被反序列化爲流。
    [Visual Basic]Dim myObject As MySerializableClass' Constructs an instance of the XmlSerializer with the type' of object that is being deserialized.Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))' To read the file, creates a FileStream.Dim myFileStream As FileStream = _New FileStream("myFileName.xml", FileMode.Open)' Calls the Deserialize method and casts to the object type.myObject = CType( _mySerializer.Deserialize(myFileStream), MySerializableClass)[C#]MySerializableClass myObject;// Constructs an instance of the XmlSerializer with the type// of object that is being deserialized.XmlSerializer mySerializer = new XmlSerializer(typeof(MySerializableClass));// To read the file, creates a FileStream.FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open);// Calls the Deserialize method and casts to the object type.myObject = (MySerializableClass) mySerializer.Deserialize(myFileStream)

有關 XML 序列化的更多示例,請參見 XML 序列化的示例

使用 XML 序列化的好處

XmlSerializer 類在您將對象序列化爲 XML 時爲您提供完整而靈活的控制。若是您正在建立 XML Web services,則能夠將控制序列化的屬性應用於類和成員以確保 XML 輸出符合特定的架構。

例如,XmlSerializer 使您可以:

  • 指定應將字段或屬性編碼爲特性仍是元素。
  • 指定要使用的 XML 命名空間。
  • 若是字段或屬性名不合適,則指定元素或特性的名稱。

XML 序列化的另外一個好處是:只要生成的 XML 流符合給定的架構,則對於所開發的應用程序就沒有約束。假定有這樣一個用於描述圖書的架構,它具備標題、做者、出版商和 ISBN 編號元素。您能夠開發一個以您但願的任何方式(例如,做爲圖書訂單,或做爲圖書清單)處理 XML 數據的應用程序。在任一種狀況下,惟一的要求是 XML 流應當符合指定的 XML 架構定義語言 (XSD) 架構。

XML 序列化注意事項

使用 XmlSerializer 類時,應考慮下列狀況:

  • 序列化數據只包含數據自己以及類的結構。不包括類型標識和程序集信息。
  • 只能序列化公共屬性和字段。若是須要序列化非公共數據,請使用 BinaryFormatter 類而不是 XML 序列化。
  • 類必須有一個將由 XmlSerializer 序列化的默認構造函數。
  • 不能序列化方法。
  • XmlSerializer 能夠以不一樣方式處理實現 IEnumerableICollection 的類(條件是這些類知足某些要求)。實現 IEnumerable 的類必須實現帶單個參數的公共 Add 方法。Add 方法的參數必須與從 GetEnumerator 方法返回的 IEnumerator.Current 屬性所返回的類型一致(多態)。除實現 IEnumerable 外還實現 ICollection 的類(如 CollectionBase)必須有一個取整數的公共 Item 索引屬性(在 C# 中爲索引器),而且它必須有一個整數類型的公共 Count 屬性。傳遞給 Add 方法的參數必須與從 Item 屬性返回的類型相同或與該類型的某個基的類型相同。對於實現 ICollection 的類,要序列化的值將從索引 Item 屬性檢索,而不是經過調用 GetEnumerator 來檢索。另外請注意,除返回另外一個集合類(實現 ICollection 的集合類)的公共字段以外,將不序列化公共字段和屬性。有關示例,請參見 XML 序列化的示例

XSD 數據類型映射

標題爲「XML Schema Part 2: Datatypes」的萬維網聯合會 (www.W3.org) 文檔指定在 XML 架構定義語言 (XSD) 架構中容許使用的簡單數據類型。對於這些數據類型中的許多類型(例如,intdecimal),在 .NET Framework 中都有對應的數據類型。可是,某些 XML 數據類型在 .NET Framework 中沒有對應的數據類型(例如,NMTOKEN 數據類型)。在這樣的狀況下,若是使用 XML 架構定義工具 (Xsd.exe) 從架構生成類,就會將適當的特性應用於字符串類型的成員,並會將其 DataType 屬性設置爲 XML 數據類型名稱。例如,若是架構包含一個數據類型爲 XML 數據類型 NMTOKEN 的、名爲「MyToken」的元素,則生成的類可能包含如下示例中的成員。

[Visual Basic]<XmlElement(DataType:="NMTOKEN")>Public MyToken As String[C#][XmlElement(DataType = "NMTOKEN")]public string MyToken;

與此相似,若是建立一個必須符合特定 XML 架構 (XSD) 的類,應當應用適當的特性並將它的 DataType 屬性設置爲所需的 XML 數據類型名稱。

有關類型映射的完整列表,請參見下列任意一個特性類的 DataType 屬性:SoapAttributeAttributeSoapElementAttributeXmlArrayItemAttributeXmlAttributeAttributeXmlElementAttributeXmlRootAttribute

相關文章
相關標籤/搜索