An unhandled exception of type 'System.Net.WebException' occurred in system.web.services.dll
Additional information: The request failed with the error message:
--
發(fā)生了什么呢?原來HTTP請(qǐng)求收到的不是“200 OK”響應(yīng)。如果你熟悉HTTP協(xié)議,你或許可以從響應(yīng)中的HTML代碼中發(fā)現(xiàn)這是一個(gè)“302 Found”響應(yīng),這意味著該請(qǐng)求被重定向到超鏈接中指定的地址。返回HTML代碼是很明智的,這樣如果一個(gè)瀏覽器因?yàn)槟承┰虿恢С种囟ㄏ虻脑挘梢园汛a顯示出來,或者在重定向過程中顯示這些代碼直到重定向完成。注意到超鏈接中包含了一個(gè)有趣的字符串“(l2z3psnhh2cf1oahmai44p21)”,顯然,我們可以推斷這就是ASP.net的會(huì)話ID,它被嵌入了我們要重定向到的位置的URL中。在客戶端代理中,我們需要做的僅僅是重新發(fā)送請(qǐng)求到這個(gè)新的URL。
無須再在Win32 WinInet API編程中跋涉,我們可以直接找到proxy類的一個(gè)屬性允許自動(dòng)重定向。用外行人的說法,就是如果我們接收到一個(gè)“302 Found”響應(yīng),就直接將請(qǐng)求重新發(fā)送到相應(yīng)中HTTP位置頭所指示的URL。當(dāng)Visual Studio.net的智能提示顯示proxy類的AllowAutoRedirect屬性時(shí),我感到這東西真是機(jī)靈得可愛。我馬上就在代碼中加上如下一行:
proxy.AllowAutoRedirect = True
我認(rèn)為這仍然比創(chuàng)建一個(gè)CookieContainer類并關(guān)聯(lián)到proxy類要容易得多,于是我又一次運(yùn)行程序。很不幸,我遭遇了如下異常(為了簡(jiǎn)潔起見有所刪節(jié)):
An unhandled exception of type 'System.InvalidOperationException' occurred
in system.web.services.dll
Additional information: Client found response content type of 'text/html; charset=utf-8',
but expected 'text/xml'.
The request failed with the error message: …
如果你看到錯(cuò)誤消息的內(nèi)容,你會(huì)發(fā)現(xiàn)你所看到的HTML頁面跟你瀏覽.ASMX文件的頁面一樣。問題是,為什么當(dāng)我傳送XML(以SOAP封裝了的形式)到Web Service服務(wù)器時(shí)它返回的卻是HTML代碼?結(jié)果證實(shí),你并沒有在SOAP封裝中發(fā)送HTTP POST請(qǐng)求,而僅僅發(fā)送了一個(gè)簡(jiǎn)單的沒有內(nèi)容的HTTP GET請(qǐng)求,因此你的Web Service服務(wù)端理所當(dāng)然地假設(shè)這個(gè)請(qǐng)求來自瀏覽器,于是它返回普通的HTML響應(yīng)。為什么會(huì)這樣呢?
如果你了解HTTP協(xié)議,你會(huì)發(fā)現(xiàn)一個(gè)HTTP客戶端在收到“302 Found”響應(yīng)時(shí)發(fā)送HTTP GET請(qǐng)求到響應(yīng)中指定的地址是合情合理的,即使初始請(qǐng)求是HTTP POST。這種方式下瀏覽器工作得很好,因?yàn)殚_始幾乎所有的請(qǐng)求都是HTTP GET類型的,只有當(dāng)你試圖傳遞數(shù)據(jù)到一個(gè)URL時(shí),才會(huì)出現(xiàn)上述失敗的結(jié)果。
理由是在傳送的數(shù)據(jù)中可能包含潛在的敏感數(shù)據(jù),因此你需要確認(rèn)是否用戶真的想向新的資源傳送數(shù)據(jù)。顯然如果你轉(zhuǎn)向基于重定向設(shè)置的新地址,你就沒能確認(rèn)用戶是否真的允許將他們的數(shù)據(jù)發(fā)送到新的地址。因此數(shù)據(jù)并沒有被發(fā)送,而代之以簡(jiǎn)單的HTTP GET請(qǐng)求。
新聞熱點(diǎn)
疑難解答
圖片精選