2011-04-26 157 views
3

我有一個供應商的extern說送我,XML測試反序列化SOAP消息

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Header> 
    <AVCabeza transactionID="000032" xmlns="http://webservices.patito/Core/"> 
    <Solicitor entityID="WEST" systemType="WEB" /> 
    </AVCabeza> 
</soap:Header> 
<soap:Body> 
    <Availability xmlns:a="http://webservices.patito/Availability/" 
     xmlns:hc="http://webservices.patito/Common/" summaryOnly="true" 
     xmlns="http://webservices.patito/og/Availability.wsdl"> 
    <a:AvailabilityDetail availReqType="Room"> 
     <a:Estadia> 
     <hc:StartDate>2009-01-05T00:00:00.0000000-05:00</hc:StartDate> 
      <hc:EndDate>2009-01-06T00:00:00.0000000-05:00</hc:EndDate> 
     </a:Estadia> 
     <a:HotelSearchCriteria>    
      <a:HotelRef chainCode="WC"/>    
     </a:HotelSearchCriteria> 
     </a:AvailabilityDetail> 
    </Availability> 
    </soap:Body> 
</soap:Envelope> 

我想解串器,所以我做到了

1)我使用的XSD的生成C#類

2)用類generate創建一個新的項目類庫。

結構

WebServicesExterns(項目) - >服務(文件夾) --->所有類

例如

namespace WebServicesExterns.Services 

<System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42"), _ 
System.SerializableAttribute(), _ 
System.Diagnostics.DebuggerStepThroughAttribute(), _ 
System.ComponentModel.DesignerCategoryAttribute("code"), _ 
System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://webservices.patito/Availability.wsdl")> _ 
Partial Public Class Availability 




'''<comentarios/> 
<System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42"), _ 
System.SerializableAttribute(), _ 
System.Diagnostics.DebuggerStepThroughAttribute(), _ 
System.ComponentModel.DesignerCategoryAttribute("code"), _ 
System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://webservices.patito/Core/"), _ 
System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://webservices.patito/Core/", IsNullable:=false)> _ 
Partial Public Class AVCabeza 

3)創建嘗試一個測試類之後解串器

using WebServicesExterns.Services; 
using System; 
using System.Collections; 
using System.IO; 
using System.Linq; 
using System.Runtime.Remoting; 
using System.Runtime.Serialization; 
using System.Xml; 
using System.Xml.Serialization; 
using NUnit.Framework; 
using System.Reflection; 
using System.Runtime.Serialization.Formatters.Soap; 


    [Test()] 
    public void ShouldDeserializerSoapMessage() 
    { 
     var message = SoapToFromFile(@"C:\rq\Availability.xml"); 
     Assert.IsNotNull(message); 
    } 


    public object SoapToFromFile(string filePath) 
    { 
     IFormatter formatter; 
     FileStream fileStream = null; 
     Object objectFromSoap = null;    

     try 
     { 
      fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); 
      formatter = new SoapFormatter(); 
      objectFromSoap = formatter.Deserialize(fileStream); 
     } 
     catch (Exception exception) 
     { 
      throw exception; 
     } 
     finally 
     { 
      if (fileStream != null) fileStream.Close(); 
     } 
     return objectFromSoap; 
    } 

因此,返回該錯誤

解析錯誤,沒有與XML密鑰 「AVCabeza」 「_p1締合體」

調試我創辦什麼_p1等於 「HTTP://webservices.patito/Core/」

顯然沒有找到「類型」AVCabeza類

怎麼了?這是供應商

新的更新

看給我

一個文件夾與結構

root 
| 
-- WSDL_XSD 
| |-XSD 
| | files with extension .xsd 
| | 
| --WS 
|  files with extension .wsdl 
|-- XMLSamples 
    |-files with xml extension that contain soap messsages 

以及我刪除XML(前面的例子)頭部

<?xml version="1.0" encoding="utf-8"?> 
<Availability xmlns:a="http://webservices.patito/Availability/" 
     xmlns:hc="http://webservices.patito/Common/" summaryOnly="true" 
     xmlns="http://webservices.patito/og/Availability.wsdl"> 
    <a:AvailabilityDetail availReqType="Room"> 
     <a:Estadia> 
     <hc:StartDate>2009-01-05T00:00:00.0000000-05:00</hc:StartDate> 
      <hc:EndDate>2009-01-06T00:00:00.0000000-05:00</hc:EndDate> 
     </a:Estadia> 
     <a:HotelSearchCriteria>    
      <a:HotelRef chainCode="WC"/>    
     </a:HotelSearchCriteria> 
     </a:AvailabilityDetail> 
</Availability> 

並將嘗試獲取des erializable供應對象,但現在失敗這個標誌

not expected "<Availability .." 

在wsdl_xsd - > WS - > WS我看到的可用性存在,所以我覺得可用性換到availabilitydetail(實際要求),這是我不能刪除 可用性對象標籤,因爲它具有兒童標籤的名稱空間spacefications

是什麼想法呢?

也許如果我刪除可用性和插入命名空間(在某種程度上)我能得到我的解串對象

回答

3

SoapFormatter不是XML序列化。您應該使用XmlSerializer類。

此外,這是一個完整的SOAP消息。您最好讓他們爲您提供WSDL並使用「添加服務參考」。這會給你一些可以爲你做序列化和反序列化的類。

+0

對不起,我不能添加Web引用,因爲存在的共同對象,我使用5 8服務和它導致衝突,所以我創建了一個代理與WSDL和生成所有類。非常感謝 – 2011-04-26 20:22:07

+1

如果你使用WSDL創建了一個代理,那麼你做了和「添加Web引用」一樣的事情。這意味着你不需要做你自己的序列化。 – 2011-04-26 20:23:09

2

當您使用xsd.exe從該XML文檔生成C#類時,第一步將獲得5個單獨的.xsd文件,從消息中提供 XSD Schema「推斷」。 (因爲在該消息中使用了大量的XML名稱空間,所以有許多XSD文件)

特別是,XSD.exe將生成代碼來描述SOAP Envelope,其中包括正文和頭文件。這可能不是您想要或需要做的事情,但是xsd.exe工具會推斷整個XML文檔的類型。

此外,xsd.exe中的推理引擎是 不準確。例如,Estadia元素的「StartDate」和「EndDate」子元素顯示爲日期。但是xsd.exe不會做出這樣的假設;它將生成一個XML模式,將這些事情標記爲字符串。還有其他類似的假設,即xsd.exe在推斷時做出的。在所有情況下,您可能都希望修改生成的xsd文件,以匹配您真正期望的內容。對於StartDate和EndDate,您想要將類型從xs:string修改爲xs:dateTime

此時,您可以使用/ c開關在.xsd文件中再次運行xsd.exe 以生成.cs源代碼。編譯獲取可用於序列化的類。

要使用生成的代碼,你會做這樣的事反序列化:

XmlSerializer s1 = new XmlSerializer(typeof(Carlos.Envelope)); 
    Envelope envelope = null; 
    using(var reader= System.IO.File.OpenText("SampleMessage.xml")) 
    { 
     envelope = (Envelope) s1.Deserialize(reader); 
    } 

然後你可以打開那個信封對象,並在其內的各種數據得到。


退一步,你可以看到你可能不應該這樣做。查看示例消息很有用也很方便,可以告訴你線路上應該看起來像什麼東西。但是,當生成代碼來處理序列化爲這些消息的類時,最好從源XSD開始 - 這可能在服務端可用。約翰桑德斯在答覆中說道。

如果您的人員可以生成示例消息,那麼他們可能擁有該消息的XSD(或等效的WSDL)。這將消除您推斷xsd的要求,然後通過上述不精確的過程對其進行修改以更改破碎的假設。

你唯一需要做的就是如果你以某種方式丟失了原來的XSD/WSDL,並且你需要重新生成它。

+0

謝謝Cheeso,那是提供者給我的 一個文件夾與它 根 - WSDL_XSD | | -XSD(擴展名爲.xsd的文件) | --WS(帶擴展名的文件。WSDL) | - XMLSamples(含皁形式交往與XML擴展名的文件) 對不起,如果我的錯誤,但我的想法是生成C#類XSD 機構獲取XML請求 的後解串後立即獲得支正確的c#類 和後反射litte。我嘗試和嘗試的 一,二和許多方法,但我甚至不能 我承認我是新的XML。 – 2011-04-30 17:26:41