2017-05-31 59 views
0

我試圖消耗第三方web服務。我製作一個請求消息,將其發送到httpclient並接收httpResponseMessage。HttpResponseMessage失敗反序列化XML,但FILESTREAM是罰款

下面是從該處理呼叫的方法的一個片段。對我的情況xml = true。

​​

運行此代碼後,嘗試反序列化流中的XML數據時會引發錯誤。它失敗並出現錯誤「根級別的數據無效」。

我註釋掉XMLMediaTypeFormatter和response.Content.Read ...以及與此

    var fileStream = File.Create("D:\\Extract\\test.txt"); 
        await response.Content.CopyToAsync(fileStream); 
        fileStream.Close(); 

其寫出有效的XML文件替換它。

在即時窗口,我跑response.Content.ReadAsStringAsync()返回的字符串值具有額外的反斜槓逃逸的內容。

例如,這是什麼,是在生成的test.txt文件:

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

,這是從ReadAsStringAsync:

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

我相信這是什麼原因造成的反序列化失敗。有沒有一個乾淨的解決方案,或者我在其他地方做錯了什麼?

+0

'<?XML版本= \ 「1.0 \」 編碼= \ 「UTF-8 \」?>'我猜你看這是什麼,當你在調試器中查看字符串的內容?如果是,那麼它看起來是正確的。調試器顯示轉義格式的字符串,因爲調試器允許您更改變量的值。所以,如果你要改變你的字符串,你需要以它在代碼中出現的相同形式輸入它。所以這不會是你的問題的原因。另外,BOM(如果存在)不應該導致xml解析器失敗。 – LB2

+0

是的,這就是我在ReadAsStringAsync()之後的字符串內容中看到的內容。我對BOM沒有把握,儘管另一個SO問題表明BOM破壞了他們的反序列化器,並且在反序列化之前扔掉了流的第一個字節。 –

+0

我不知道閱讀文件是否會拋棄BOM,這就是爲什麼它可以工作。首先嚐試將其讀入字符串緩衝區,然後在調試器中查看結果字符串是否包含BOM(或可能存入內存緩衝區,並檢查第一對字節以查看它們是否爲BOM)? – LB2

回答

0

的問題是在代碼

   await response.Content.CopyToAsync(fileStream); 
       fileStream.Close(); 

       //This fails with "the data at the root level is invalid" 
       XmlMediaTypeFormatter xmlFormatter = new XmlMediaTypeFormatter { UseXmlSerializer = true }; 
       var content = response.Content.ReadAsAsync<T>(new Collection<MediaTypeFormatter> { xmlFormatter }); 

HTTP響應只能使用一次消耗以下塊。換句話說,響應不會讀入某個可以從中讀取多個讀取的緩衝區。它直接從插槽讀取它。所以一旦閱讀,就不能再讀。

上面,您將響應複製到文件中。這會消耗響應,並且不再可以再次讀取。因此,當您嘗試在分配給content時再次閱讀它時,它什麼都不讀,所以XML解析器(在格式化程序中)拋出xml語法錯誤b/c,它基本上收到一個空字符串。

不知道爲什麼你保存到文件中,但一旦保存到文件中,你可以簡單地讀取該文件併發送其內容的XML解析器,和你的代碼現在應該工作。當然,如果你刪除保存到文件,你應該能夠閱讀和解析響應的內容就好了。

+0

我會更新帖子。我爲調試目的添加了文件寫入。主要查看是否有BOM可能不會顯示在即時窗口中。第二個電話原本是唯一的電話,並失敗。 –

+0

@DavidJacobsen我看到,如果您取消註釋,會發生什麼情況,而是讀取文件的內容並嘗試反序列化。那它有用嗎? – LB2

+0

是的。這是爲什麼我認爲有一個「更清潔」的答案,而不是與第三方報告的錯誤的一部分。 –