• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎(chǔ)} {C++ 高級} {C#界面,C++核心算法} {設(shè)計模式} {C#基礎(chǔ)}

            XmlSerializer 常見問題疑難解答

            http://www.microsoft.com/china/MSDN/library/data/xml/Usdnxmlnettrblshtxsd.mspx?mfr=true


            XmlSerializer 常見問題疑難解答

            發(fā)布日期: 6/30/2004 | 更新日期: 6/30/2004

            Christoph Schittko

            適用于:
            Microsoft ?Visual Studio ?.NET

            摘要:Christoph Schittko 討論了各種相關(guān)技巧,以便診斷在使用 .NET 框架中的 XML 序列化技術(shù)將 XML 轉(zhuǎn)換為對象(以及反向轉(zhuǎn)換)時發(fā)生的常見問題。

            *
            本頁內(nèi)容
            簡介 簡介
            XmlSerializer 的內(nèi)部工作方式 XmlSerializer 的內(nèi)部工作方式
            序列化錯誤 序列化錯誤
            聲明序列化類型 聲明序列化類型
            反序列化 XML 時發(fā)生的問題 反序列化 XML 時發(fā)生的問題
            來自構(gòu)造函數(shù)的異常 來自構(gòu)造函數(shù)的異常
            小結(jié) 小結(jié)
            致謝 致謝

            簡介

            .NET 框架中的 XmlSerializer 是一種很棒的工具,它將高度結(jié)構(gòu)化的 XML 數(shù)據(jù)映射到 .NET 對象。XmlSerializer 在程序中通過單個 API 調(diào)用來執(zhí)行 XML 文檔和對象之間的轉(zhuǎn)換。轉(zhuǎn)換的映射規(guī)則在 .NET 類中通過元數(shù)據(jù)屬性來表示。這一編程模型帶有自己的錯誤類別,開發(fā)人員需要了解如何診斷這些錯誤。例如,元數(shù)據(jù)屬性必須描述序列化程序可以處理的 XML 格式的所有變體。本文研究了在使用 XmlSerializer 構(gòu)建基于 XML 的解決方案時可能發(fā)生的各種錯誤,并且討論了用來診斷這些錯誤的技巧和工具。

            XmlSerializer 的內(nèi)部工作方式

            為了有效地解決在 XML 序列化過程中出現(xiàn)的問題,需要了解一下在非常簡單的 XmlSerializer 接口的內(nèi)部發(fā)生了什么事情。與傳統(tǒng)的分析范型相反,.NET 框架中 System.Xml.Serialization 命名空間的 XmlSerializer 將 XML 文檔綁定到 .NET 類的實例。程序員不再需要編寫 DOM 或 SAX 分析代碼,而是通過直接在這些類中附加 .NET 元數(shù)據(jù)屬性來聲明性地設(shè)置綁定規(guī)則。因為所有分析規(guī)則都是通過屬性表示的,所以 XmlSerializer 的接口非常簡單。它主要由兩個方法組成:Serialize() 用于從對象實例生成 XML;Deserialize() 用于將 XML 文檔分析成對象圖。

            在使用強類型的、能夠完美地映射到編程對象的結(jié)構(gòu)嚴謹?shù)?XML 格式時,這種方法非常有效。如果格式由 W3C架構(gòu)定義,并且該架構(gòu)由不帶混合型內(nèi)容或且不過度使用通配符(xs:any 和 xs;anyAttribute)的 complexType 組成,則 XML 序列化是處理該數(shù)據(jù)的好方法。

            面向消息的應(yīng)用程序就是一個很好的例子,這些應(yīng)用程序之間的交換格式已預先定義。因為許多消息驅(qū)動的企業(yè)應(yīng)用程序都具有非常高的吞吐量要求,所以 Serialize() 和 Deserialize() 方法被設(shè)計為具有很高的執(zhí)行速度。實際上,正是 XmlSerializer 為 System.Messaging 命名空間中的具有高度可伸縮性的庫、ASP.NET Web 服務(wù) BizTalk Server 2004 提供了動力。

            為獲得 XmlSerializer 的高性能,需要付出雙重代價。首先是與給定 XmlSerializer 可以處理的 XML 格式有關(guān)的靈活性,其次是實例的構(gòu)造需要進行大量的處理。

            當您實例化 XmlSerializer 時,必須傳遞您試圖通過該序列化程序?qū)嵗M行序列化和反序列化的對象的類型。序列化程序?qū)z查該類型的所有公共字段和屬性,以了解一個實例在運行時引用哪些類型。接下來,它將為一組類創(chuàng)建 C# 代碼,以便使用 System.CodeDOM 命名空間中的類處理序列化和反序列化。在此過程中,XmlSerializer 將檢查 XML 序列化屬性的反射類型,以便根據(jù) XML 格式定義來自定義所創(chuàng)建的類。這些類隨后被編譯為臨時程序集,并由 Serialize() 和 Deserialize() 方法調(diào)用以執(zhí)行 XML 到對象的轉(zhuǎn)換。

            這個設(shè)置 XmlSerializer 的精巧過程和聲明性編程模型導致了三類錯誤,其中一些錯誤可能很難解決:

            ?

            所生成的序列化類期望被序列化的對象完全符合元數(shù)據(jù)屬性所定義的類型結(jié)構(gòu)。如果 XmlSerializer 遇到未聲明(顯式聲明或者是通過 XML 序列化屬性聲明)的類型,則對象將無法序列化。

            ?

            XML 文檔在以下情況下無法反序列化:該文檔的根元素不能映射對象類型;該文檔的格式不正確,例如包含 XML 規(guī)范中定義為非法的字符;該文檔違反基礎(chǔ)架構(gòu)的限制(在某些情形下)。

            ?

            最后,序列化類的創(chuàng)建及其隨后的編譯可能由于多種不同的原因而失敗。當傳遞給構(gòu)造函數(shù)的類型或者由該類型引用的類型實現(xiàn)了不受支持的接口或者不能滿足 XmlSerializer 施加的限制時,類的創(chuàng)建可能會失敗。

            當附加的屬性生成無法編譯的 C# 代碼時,編譯步驟可能會失敗。編譯步驟也可能由于與安全有關(guān)的原因而失敗。

            下面各個部分將更深入地研究這些情況,并提供有關(guān)如何解決這些問題的指導和建議。

            序列化錯誤

            我們要研究的第一類錯誤發(fā)生在 Serialize() 方法中。當在運行時傳遞給該方法的對象圖中的類型與在設(shè)計時在類中聲明的類型不匹配時,將發(fā)生此類錯誤。您可以通過字段或?qū)傩缘念愋投x來隱式聲明類型,也可以通過附加序列化屬性來顯式聲明類型。

            typedecl

            1. 對象圖中的類型聲明

            這里需要指出的是,依靠繼承是不夠的。開發(fā)人員必須通過將 XmlInclude 屬性附加到基類,或者通過將 XmlElement 屬性附加到字段(這些字段可以容納從所聲明的類型派生的類型的對象),來聲明 XmlSerializer 的派生類型。

            例如,請看一下以下類層次結(jié)構(gòu):

            public class Base
            {
               public string Field;
            }
            public class Derived
            {
              public string AnotherField;
            }
            public class Container
            {
              public Base MyField;
            }
            如果您依賴繼承并且編寫了與下面類似的序列化代碼:
            Container obj = new Container();
            obj.MyField = new Derived(); // legal assignment in the 
                                         //.NET type system
            // ...
            XmlSerializer serializer = new XmlSerializer( typeof( Container ) );
            serializer.Serialize( writer, obj ); // Kaboom!
            

            您將得到發(fā)自 Serialize() 方法的異常,這是因為沒有 XmlSerializer 的顯式類型聲明。

            發(fā)自 XmlSerializer 的異常

            診斷這些問題的根源在開始時可能比較困難,這是因為來自 XmlSerializer 的異??雌饋聿]有提供有關(guān)其產(chǎn)生原因的大量信息;至少,它們沒有在開發(fā)人員通常會查看的地點提供信息。

            在大多數(shù)情況下,當發(fā)生錯誤時,Serialize、Deserialize 甚至 XmlSerializer 構(gòu)造函數(shù)都會引發(fā)一個相當普通的 System.InvalidOperationException。該異常類型可以在 .NET 框架中的許多地方出現(xiàn);它根本不是 XmlSerializer 所特有的。更糟糕的是,該異常的 Message 屬性也僅產(chǎn)生非常普通的信息。在上述示例中,Serialize() 方法會引發(fā)帶有以下消息的異常:

            There was an error generating the XML document.
            

            該消息最多也就是令人討厭的,因為當您看到 XmlSerializer 引發(fā)異常時,就已經(jīng)猜到了這一點。現(xiàn)在,您只好無奈地發(fā)現(xiàn)該異常的 Message 無法幫助您解決問題。

            奇怪的異常消息和非描述性的異常類型反映了本文前面介紹的 XmlSerializer 內(nèi)部工作方式。Serialize() 方法會捕獲序列化類中引發(fā)的所有異常,將它們包裝到 InvalidOperationException 中,然后將該異常包沿著堆棧向上傳遞。

            讀取異常消息

            得到“實際”的異常信息的竅門是檢查該異常的 InnerException 屬性。InnerException 引用了從序列化類內(nèi)部引發(fā)的實際異常。它包含有關(guān)該問題及其發(fā)生地點的非常詳細的信息。您在運行上述示例時捕獲的異常將包含帶有以下消息的 InnerException:

            The type Derived was not expected. Use the XmlInclude or SoapInclude 
            attribute to specify types that are not known statically.
            

            您可以通過直接檢查 InnerException 或者通過調(diào)用該異常的 ToString() 方法來得到此消息。下面的代碼片段演示了一個異常處理程序,它寫出了在反序列化對象的過程中發(fā)生的所有異常中的信息:

            public void SerializeContainer( XmlWriter writer, Container obj )
            {
              try
              {
                // Make sure even the construsctor runs inside a
                // try-catch block
                XmlSerializer ser = new XmlSerializer( typeof(Container));
                ser.Serialize( writer, obj );
              }
              catch( Exception ex )               
              {                                   
                DumpException( ex );             
              }                                   
            }
            public static void DumpException( Exception ex )
            {
              Console.WriteLine( "--------- Outer Exception Data ---------" );        
              WriteExceptionInfo( ex );
              ex = ex.InnerException;                     
              if( null != ex )               
              {                                   
                Console.WriteLine( "--------- Inner Exception Data ---------" );                
                WriteExceptionInfo( ex.InnerException );    
                ex = ex.InnerException;
              }
            }
            public static void WriteExceptionInfo( Exception ex )
            {
              Console.WriteLine( "Message: {0}", ex.Message );                  
              Console.WriteLine( "Exception Type: {0}", ex.GetType().FullName );
              Console.WriteLine( "Source: {0}", ex.Source );                    
              Console.WriteLine( "StrackTrace: {0}", ex.StackTrace );           
              Console.WriteLine( "TargetSite: {0}", ex.TargetSite );            
            }
            

            聲明序列化類型

            要解決上述示例中的問題,您只需讀取 InnerException 的消息并實現(xiàn)建議的解決方案。傳遞給 Serialize 方法的對象圖中的一個字段引用了一個類型為 Derived 的對象,但并未將該字段聲明為序列化 Derived 類型的對象。盡管該對象圖在 .NET 類型系統(tǒng)中完全合法,但 XmlSerializer 的構(gòu)造函數(shù)在遍歷容器類型的字段時,并不知道為 Derived 類型的對象創(chuàng)建了序列化代碼,這是因為它沒有找到對 Derived 類型的引用。

            要向 XmlSerializer 聲明其他字段和屬性類型,您擁有多種選擇。您可以通過 XmlInclude 屬性(由異常消息提示)聲明基類上的派生類型,如下所示:

            [System.Xml.Serialization.XmlInclude( typeof( Derived ) )]
            public class Base
            {
                // ...
            }
            

            通過附加 XmlInclude 屬性,可以讓 XmlSerializer 在字段或?qū)傩员欢x為 Base 類型時序列化引用 Derived 類型對象的字段。

            或者,您還可以僅在單個字段或?qū)傩陨下暶饔行ь愋?,而不是在基類上聲明派生類型。您可以?XmlElement、XmlAttribute 或 XmlArrayItem 屬性附加到字段,并且聲明該字段或?qū)傩钥梢砸玫念愋汀H缓?,XmlSerializer 的構(gòu)造函數(shù)會將序列化和反序列化這些類型所需的代碼添加到序列化類中。

            讀取 StackTrace

            InnerException 的 Message 屬性并不是唯一包含有價值信息的屬性。StackTrace 屬性傳達了更多有關(guān)錯誤根源的詳細信息。在堆棧跟蹤的最頂端,您可以找到首先引發(fā)異常的方法的名稱。臨時程序集中的方法名稱對于序列化類遵循格式 Write_,對于反序列化類則遵循格式 Read_。在具有上述錯誤命名空間的示例中,您可以看到異常源自名為 Read1_MyClass 的方法。稍后,我將向您說明如何使用 Visual Studio 調(diào)試器設(shè)置斷點并單步執(zhí)行此方法。不過,首先讓我們看一下圍繞反序列化 XML 文檔發(fā)生的常見問題。

            反序列化 XML 時發(fā)生的問題

            將 XML 文檔反序列化為對象圖不像將對象圖序列化為 XML 那樣容易出錯。當對象不十分匹配類型定義時,XmlSerializer 會非常敏感,但如果反序列化的 XML 文檔不十分匹配對象,則它會非常寬容。對于與反序列化對象中的字段或?qū)傩圆粚?yīng)的 XML 元素,XmlSerializer 不再引發(fā)異常,而只是簡單地引發(fā)事件。如果您需要跟蹤反序列化的 XML 文檔與 XML 格式之間的匹配程度,則可以注冊這些事件的處理程序。然而,您不需要向 XmlSerializer 注冊事件處理程序以正確處理未映射的 XML 節(jié)點。

            在反序列化過程中,只有幾種錯誤條件會導致異常。最常見的條件有:

            ?

            根元素的名稱或其命名空間不匹配期望的名稱。

            ?

            枚舉數(shù)據(jù)類型呈現(xiàn)未定義的值。

            ?

            文檔包含非法 XML。

            就像序列化的情形一樣,每當發(fā)生問題時,Deserialize() 方法都會引發(fā)帶有以下消息的 InvalidOperation 異常

            There is an error in XML document (, ).
            

            該異常通常在 InnerException 屬性中包含真正的異常。InnerException 的類型隨讀取 XML 文檔時發(fā)生的實際錯誤而有所不同。如果序列化程序無法用傳遞給構(gòu)造函數(shù)的類型、通過 XmlInclude 屬性指定的類型或者在傳遞給 XmlSerializer 構(gòu)造函數(shù)的某個更為復雜的重載的 Type[] 中指定的類型來匹配文檔的根元素,則 InnerException 為 InvalidCastException。請記住,XmlSerializer 將查看 Qname(即元素的名稱)和命名空間,以確定要將文檔反序列化為哪個類。它們都必須匹配 .NET 類中的聲明,以便 XmlSerializer 正確標識與文檔的根元素相對應(yīng)的類型。

            讓我們看一個示例:

            [XmlRoot( Namespace="urn:my-namespace" )]
            public class MyClass
            {
              public string MyField;
            }
            

            反序列化以下 XML 文檔將導致異常,因為 MyClass 元素的 XML 命名空間并不像通過 .NET 類上的 XmlRoot 屬性所聲明的那樣是 urn:my-namespace。

            <MyClass> <MyField>Hello, World</MyField> </MyClass>
            

            讓我們更進一步地觀察一下該異常。異常 Message 比您從 Serialize() 方法中捕獲的消息更具描述性;至少它引用了文檔中導致 Deserialize() 失敗的位置。盡管如此,當您處理大型 XML 文檔時,查看文檔并確定錯誤可能不會如此簡單。InnerException 又一次提供了更好的信息。這一次,它顯示:

            <MyClass xmlns=''> was not expected.
            

            該消息仍然有一些模糊,但它的確向您指明了導致問題的元素。您可以回頭仔細檢查一下 MyClass 類,并將元素名稱和 XML 命名空間與 .NET 類中的 XML 序列化屬性進行比較。

            反序列化無效的 XML

            另一個經(jīng)常報告的問題是無法反序列化無效的 XML 文檔。XML 規(guī)范禁止在 XML 文檔中使用某些控制字符。然而,有時您仍然會收到包含這些字符的 XML 文檔。正如您猜想的那樣,問題暴露在 InvalidOperationException 中。盡管如此,在這種特殊情況下,InnerException 的類型是 XmlException。InnerException 的消息正中要害:

            hexadecimal value <value>, is an invalid character
            

            如果您通過將其 Normalization 屬性設(shè)置為 true 的 XmlTextReader 進行反序列化,則可以避免此問題。遺憾的是,ASP.NET Web 服務(wù)在內(nèi)部使用的 XmlTextReader 將其 Normalization 屬性設(shè)置為 false;也就是說,它將不會反序列化包含這些無效字符的 SOAP 消息。

            來自構(gòu)造函數(shù)的異常

            本文討論的最后一類問題發(fā)生在 XmlSerializer 的構(gòu)造函數(shù)對傳入的類型進行分析的時候。請記住,構(gòu)造函數(shù)將遞歸檢查類型層次結(jié)構(gòu)中的每個公共字段和屬性,以便創(chuàng)建用來處理序列化和反序列化的類。然后,它將即時編譯這些類,并加載得到的程序集。

            在這一復雜的過程中,可能會發(fā)生許多不同的問題:

            ?

            根元素的聲明類型或者由屬性或字段引用的類型不提供默認的構(gòu)造函數(shù)。

            ?

            層次結(jié)構(gòu)中的某個類型實現(xiàn)了集合接口 Idictionary

            ?

            執(zhí)行對象圖中某個類型的構(gòu)造函數(shù)或?qū)傩栽L問器時,需要提升安全權(quán)限。

            ?

            生成的序列化類的代碼無法編譯。

            試圖向 XmlSerializer 構(gòu)造函數(shù)傳遞不可序列化的類型也會導致 InvalidOperationException,但這一次該異常不會包裝其他異常。Message 屬性包含對構(gòu)造函數(shù)拒絕傳入“類型”的原因的充分解釋。試圖序列化未實現(xiàn)不帶參數(shù)的構(gòu)造函數(shù)(默認構(gòu)造函數(shù))的類的實例時,將產(chǎn)生帶有以下 Message 的異常:

            Test.NonSerializable cannot be serialized because it does not have a default public constructor.
            

            另一方面,解決編譯錯誤是非常復雜的。這些問題暴露在帶有以下消息的 FileNotFoundException 中:

            File or assembly name abcdef.dll, or one of its dependencies, was not found. File name: "abcdef.dll"
               at System.Reflection.Assembly.nLoad( ... )
               at System.Reflection.Assembly.InternalLoad( ... )
               at System.Reflection.Assembly.Load(...)
               at System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly() 
                ....
            

            您可能不知道“找不到文件”異常與實例化序列化程序?qū)ο笾g有什么關(guān)系,但請記?。簶?gòu)造函數(shù)寫入 C# 文件并試圖編譯這些文件。該異常的調(diào)用堆棧提供了一些有用的信息,為這種懷疑提供了依據(jù)。當 XmlSerializer 試圖加載由調(diào)用 System.Reflection.Assembly.Load 方法的 CodeDOM 生成的程序集時,發(fā)生了該異常。該異常沒有提供有關(guān) XmlSerializer 根據(jù)推測要創(chuàng)建的程序集不存在的原因的解釋。通常,該程序集不存在的原因是編譯失敗,這是由于序列化屬性生成了 C# 編譯器無法編譯的代碼,但這種情況很少出現(xiàn)。

            當 XmlSerializer 運行時所屬的帳戶或安全環(huán)境無法訪問 temp 目錄時,也會發(fā)生該錯誤。

            XmlSerializer 所引發(fā)的任何異常錯誤消息都不包含實際的編譯錯誤,甚至連 InnerException 也不包含實際的編譯錯誤。這使得解決這些異常變得非常困難,直到 Chris Sells 發(fā)布了他的 XmlSerializerPrecompiler 工具。

            XmlSerializerPreCompiler

            XmlSerializer PreCompiler 是一個命令行程序,它執(zhí)行與 XmlSerializer 的構(gòu)造函數(shù)相同的步驟。它可分析類型,生成序列化類,并編譯這些類 — 因為它被純粹設(shè)計為故障排除工具,所以它可以安全地向控制臺寫入任何編譯錯誤。

            該工具使用起來非常方便。您只需使該工具指向包含導致異常的類型的程序集,并指定要預編譯的類型。讓我們看一個示例。當您將 XmlElement 或 XmlArrayItem 屬性附加到定義為交錯數(shù)組的字段時,會發(fā)生一個經(jīng)常報告的問題,如下面的示例所示:

            namespace Test
            {
              public class StringArray
              {
                [XmlElement( "arrayElement", typeof( string ) )]
                public string [][] strings;
              }
            }
            

            在為類型 Test.StringArray 實例化 XmlSerializer 對象時,XmlSerializer 構(gòu)造函數(shù)會引發(fā) FileNotFoundException。如果您編譯該類并試圖序列化該類的實例,將得到 FileNotFoundException,但不會得到有關(guān)該問題實質(zhì)的線索。XmlSerializerPreCompiler 可以為您提供缺少的信息。在我的示例中,StringArray 類被編譯為名為 XmlSer.exe 的程序集,并且我必須用下面的命令行運行該工具:

            XmlSerializerPreCompiler.exe XmlSer.exe Test.StringArray
            

            第一個命令行參數(shù)指定了程序集,第二個參數(shù)定義了該程序集中要預編譯的類。該工具會向命令窗口寫入大量信息。

            stringarray

            2. XmlSerializerPreCompiler 命令窗口輸出

            需要查看的重要代碼行是具有編譯錯誤的代碼行以及兩個與以下內(nèi)容類似的代碼行:

            XmlSerializer-produced source:
            C:\DOCUME~1\\LOCALS~1\Temp\.cs
            

            現(xiàn)在,XmlSerializerPreCompiler 為我們提供了編譯錯誤以及含有無法編譯的代碼的源文件的位置。

            調(diào)試序列化代碼

            通常情況下,XmlSerializer 會在不再需要序列化類的 C# 源文件時將其刪除。然而,有一個未經(jīng)證實的診斷開關(guān),可用來指示 XmlSerializer 將這些文件保留在硬盤上。您可以在應(yīng)用程序的 .config 文件中設(shè)置此開關(guān):

            <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <switches> <add name="XmlSerialization.Compilation" value="4" /> </switches> </system.diagnostics> </configuration>
            

            若此開關(guān)出現(xiàn)在 .config 文件中,C# 源文件將保留在 temp 目錄中。如果您使用的計算機運行 Windows 2000 或更高版本,則 temp 目錄的默認位置是 \Documents and Settings\\LocalSettings\Temp 或 \Temp(對于在 ASP.NET 帳戶下運行的 Web 應(yīng)用程序)。這些 C# 文件很容易丟失,因為它們的文件名看起來非常奇怪并且是隨機生成的,例如:bdz6lq-t.0.cs。XmlSerializerPreCompiler 可設(shè)置該診斷開關(guān),因此您可以在記事本或 Visual Studio 中打開這些文件,以檢查 XmlSerializerPreCompiler 對其報告編譯錯誤的代碼行。

            您甚至可以逐句執(zhí)行這些臨時序列化類,因為診斷開關(guān)還可以將含有調(diào)試符號的 .pdb 文件保留在硬盤上。如果您需要在序列化類中設(shè)置斷點,則可以在 Visual Studio 調(diào)試器下運行應(yīng)用程序。一旦您在輸出窗口中看到相關(guān)消息,表明應(yīng)用程序已經(jīng)從 temp 目錄中加載了具有這些奇特名稱的程序集,就可以打開具有相應(yīng)名稱的 C# 文件,然后像在您自己的代碼中一樣設(shè)置斷點。

            assemblyloaded

            3. 來自診斷開關(guān)的編譯錯誤輸出

            在序列化類中設(shè)置斷點之后,您需要執(zhí)行代碼以調(diào)用 XmlSerializer 對象上的 Serialize() 或 Deserialize() 方法。

            您只能調(diào)試序列化和反序列化,而不能調(diào)試在構(gòu)造函數(shù)中運行的代碼生成過程。

            通過在序列化類中單步執(zhí)行,您能夠查明每個序列化問題。如果您要單步執(zhí)行 SOAP 消息的反序列化,則可以使用上述技巧,這是因為 ASP.NET Web 服務(wù)和 Web 服務(wù)代理是在 XmlSerializer 之上構(gòu)建的。您需要做的只是將診斷開關(guān)添加到您的 config 文件中,然后在反序列化消息的類中設(shè)置斷點。如果 WSDL 在生成代理類時沒有準確地反映消息格式,則我偶爾會使用上述技巧來判斷正確的序列化屬性集。

            小結(jié)

            這些提示應(yīng)該可以幫助您診斷 XmlSerializer 中的序列化問題。您遇到的大多數(shù)問題都源自 XML 序列化屬性的錯誤組合,或源自與要反序列化的類型不匹配的 XML。序列化屬性控制序列化類的代碼生成,并且可能導致編譯錯誤或運行時異常。通過仔細地檢查由 XmlSerializer 引發(fā)的異常,可幫助您識別運行時異常的根源。如果您需要進一步診斷問題,則可以使用 XmlSerializerPreCompiler 工具來幫助您查找編譯錯誤。如果任一種方法都不能幫助您找到問題的根源,則可以檢查自動創(chuàng)建的序列化類的代碼,并在調(diào)試器中逐句執(zhí)行這些代碼。

            posted on 2006-04-12 12:34 夢在天涯 閱讀(1770) 評論(0)  編輯 收藏 引用 所屬分類: C#/.NET

            公告

            EMail:itech001#126.com

            導航

            統(tǒng)計

            • 隨筆 - 461
            • 文章 - 4
            • 評論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1807503
            • 排名 - 5

            最新評論

            閱讀排行榜

            国产 亚洲 欧美 另类 久久| 亚洲精品乱码久久久久久不卡| 国产aⅴ激情无码久久| 欧美黑人激情性久久| 欧美牲交A欧牲交aⅴ久久| 久久久婷婷五月亚洲97号色| 国产精品久久影院| 香蕉久久久久久狠狠色| 浪潮AV色综合久久天堂| 久久一本综合| 性欧美丰满熟妇XXXX性久久久| 久久精品国产只有精品2020| 久久久久久av无码免费看大片| 精品久久久久国产免费| 一本久久精品一区二区| 国产精品禁18久久久夂久| 四虎亚洲国产成人久久精品| 欧美日韩精品久久久久| 91秦先生久久久久久久| 国产精品VIDEOSSEX久久发布| 久久久免费观成人影院| 久久久久人妻一区精品色| 久久久久一本毛久久久| 国产精品无码久久久久久| 久久亚洲AV无码精品色午夜麻豆| 久久天堂电影网| 色狠狠久久AV五月综合| 欧美午夜精品久久久久久浪潮| 久久精品成人免费网站| 午夜精品久久久久久中宇| 国产精品99久久久精品无码| 精品免费久久久久国产一区| 精品久久久久久国产91| 久久国产精品一区二区| 2021精品国产综合久久| 久久久久久夜精品精品免费啦| 久久妇女高潮几次MBA| 伊人精品久久久久7777| 亚洲精品综合久久| 久久这里只有精品首页| 亚洲色欲久久久综合网东京热|