2011-08-30 23 views
0

嗨,無法反序列化具有根名稱「Binary」和根名稱空間的XML主體?

我(客戶端)試圖用ASP.NET WCF web服務進行溝通,一路上都來解決這個問題(這裏的更多信息:Connect to a password protected server with WCF over HTTP)。

當運行請求方法:

var proxy = factory.CreateChannel(); 
var response = proxy.GetMyData(id); 

我得到以下異常:

無法反序列化XML主體與根名稱「二進制」和根命名空間'(操作「GetMyData」和使用XmlSerializer的合同('ICFService','http://tempuri.org/'))。確保將與XML相對應的類型添加到服務的已知類型集合中。說明:執行當前Web請求期間發生未處理的異常。請查看堆棧跟蹤以獲取有關該錯誤的更多信息以及源代碼的位置。異常詳細信息:System.Runtime.Serialization.SerializationException:無法使用XmlSerializer反轉序列化具有根名稱'Binary'和根名稱空間''(用於操作'GetMyData'和合同('ICFService','http://tempuri.org/'))的XML主體。確保將與XML相對應的類型添加到服務的已知類型集合中。

難道這是一個編碼問題?我如何解決它?

BestRegards

EDIT1:我添加下面一行到 「服務」 的接口:

[ServiceKnownType(typeof(MyObject))] 

但這並不解決問題。

我也想補充一點,一個新的異常已經斌現在拋出:

在根級別的數據無效。行1,位置1. 描述:執行當前Web請求期間發生未處理的異常。請查看堆棧跟蹤以獲取有關該錯誤的更多信息以及源代碼的位置。 異常詳細信息:System.Xml.XmlException:根級別的數據無效。第1行,位置1.

這通常是我得到的第一個異常,但是當再次嘗試時,我得到另一個異常?

webservice被設置爲返回兩種類型的XML文檔,真正的消息包含一些信息並在我的應用程序中使其失效我已經使用XmlRoot和XmlElement屬性創建了corsponding類(這是我添加的類如服務界面所知的那樣)。可以返回的其他消息將只包含一個字符串,當發生這種情況時,可能會在我的客戶端拋出異常。因爲它試圖將數據變爲不支持它的類型。當我得到一個propper響應時,第二個異常(根級數據無效,第1行,位置1)可能是第一個異常(無法反序列化具有根名稱Binary的XML主體)我收到不支持的消息。

我認爲屬性和的ChannelFactory應該可以很容易,但我不能看到XML我回來因此Im現在想的我的解決方案切換到簡單的工作與XMLDocumet類。這不是一個好的解決方案,但我會看到發生了什麼事情。

EDIT2

如果我將自己的計算機上運行鍼對web服務的URL我會得到如下答覆:

<Error><code>E50</code><desc>IP Not Allowed</desc></Error> 

僅此而已,如果我正確的服務器上運行(我的主機)重播應根據客戶是這樣的:

<Desc> 
<Make cfe_code="98" cfe_value="Volkswagen" label="Märke" value="Volkswagen"/> 
<ModelName cfe_code="99" cfe_value="Touareg" label="Modell" value="Touareg"/> 
<BodyType cfe_code="212" cfe_value="22" label="Kaross" value="SUV"/> 
... 
</Desc> 

Ë dit3:

現在我已經試過這個代碼在主機服務器上:

public XDocument GetMyData(string regNr) 
{ 
    WebClient wc = new WebClient(); 
    wc.Credentials = new NetworkCredential("MyName", "MyPassword"); 

    Stream s = wc.OpenRead("http://MyServer.com/ag/get?UID=9999999999.eu_vddsall_xml&VINREG=" + regNr + "&LANG=sv"); 

    // return an XDocument for LINQ 
    XmlTextReader xmlReader = new XmlTextReader(s); 
    XDocument xdoc = XDocument.Load(xmlReader); 
    xmlReader.Close(); 

    xdoc.Save(HostingEnvironment.MapPath("~/App_Data/Files/Xml/") + DateTime.Now.ToString("hhmmssfff") + ".xml"); 

    return xdoc; 
} 

而這個偉大的工程!我得到一個包含以下內容的XML文件:

<?xml version="1.0" encoding="utf-8"?> 

<Desc> 
<Vin cfe_code="11" cfe_value="X" label="Chassie nr" value="X" /> 
<Make cfe_code="98" cfe_value="Volvo" label="Märke" value="Volvo" /> 
<ModelName cfe_code="99" cfe_value="S70" label="Modell" value="S70" /> 
<BodyType cfe_code="212" cfe_value="1" label="Kaross" value="Sedan" /> 
... 
</Desc> 

那麼,爲什麼不是我的WCF版本的工作?

+0

您可能想要編輯您的問題,並讓大家知道您已將[ServiceKnownType(typeof(MyObject))]添加到ICFService接口,但這不會改變任何東西 - 否則人們會從那裏開始:) – Tim

+0

@Tim>謝謝!完成。 – Banshee

回答

0

這是我學到了什麼:

WCF能夠建立REST服務,但WCF不提供這種服務的消費更多的幫助。相反,您應該使用WebClient或HttpWebRequest與REST服務進行通信。然而,WCF確實提供了一種與SOAP服務進行通信的方式,否則這將很難做到。

因此,我的帖子的Edit3是與REST服務進行通信的正確方式。

在我的情況下,xDocument會將WebClient的輸出解析爲XDocument。然後我將手動將此XDocument轉換爲我的視圖類(ASP.NET MVC)

3

鑑於你linked question,好像你是在爲你的客戶工廠使用webHttpBinding。如果是這種情況下,結合在內部使用WebMessageEncodingBindingElement,它定義了複合編碼器讀取來自線消息。該編碼器具有三個內編碼器,每一個負責處理特定內容類型:

  1. 「文本」的編碼器,負責處理XML內容(文字/ XML,應用/ XML等);
  2. 一個 「JSON」 編碼器,負責處理JSON內容(文字/ JSON,應用/ JSON,等);
  3. 「二進制」或「原始」編碼器,負責處理所有其他內容類型。

的二進制編碼器暴露與單一元件(稱爲<Binary>)主體的消息,並且實際的HTTP體作爲內容base64編碼數據。因此,您可能擁有的是不返回XML數據的服務器(或者至少不包含XML內容類型),因此編碼器公開的XML不是XmlSerializer預期的。

檢查與網絡工具如小提琴手,看看服務器實際上返回。

+0

謝謝!問題是,web服務只會將適當的數據返回給特定的IP,在這種情況下,我的主機服務器。我沒有完全訪問此服務器,所以我不能運行小提琴或任何類似的東西。如果我嘗試從我自己的計算機請求響應,我會收到一個小字符串,請參閱Edit2。雖然是建立一個使用XMLDocument的簡單方法,但是這將使檢查返回的XML文檔變得更加容易,但它不會像現在這樣的好解決方案。 – Banshee

+0

請仔細閱讀Edit3 – Banshee

+0

您需要找出服務器正在使用的授權策略;如果服務器只將正確的數據返回給特定的IP,那麼您將無法從另一臺機器使用它。你提到你並不是無法訪問該服務,但是你需要以某種方式訪問​​它(或者與可能的人交談)以允許你的客戶端訪問它。這與WCF沒有任何關係。 – carlosfigueira

相關問題