同事報案,呼叫Web Service時一直出現HTTP 400 Bad Request的錯誤訊息,接著我花了近一個小時才抓出蟲來。

同樣的Web Service有其他程式在使用,可順利被呼叫無虞,呼叫程式碼看來正常,雖然我有點懷疑其中一個應是string的參數,怎麼變成了XmlNode,但在經驗中,Visual Studio在Add Web Reference後會自動打理一切,參數型別出問題的機率不高,加上重新Add Web Reference後仍是如此,便未再深究。

看不出所以然,召喚神獸--Microsoft Network Monitor監看封包,發現一處異常! 在Soap Body中,呼叫WebMethod時少了一個參數,就是剛才說印象中是string,程式中卻是XmlNode的那個參數。這讓我重啟調查,查了Web Service的程式碼,確認我沒記錯,該參數型別應為string無誤。但有趣的問題來了,明明已重加Web Service Reference,看WSDL中也都是<s:element minOccurs="0" maxOccurs="1" name="Context" type="s:string" />,WDSL也找不到任何地方有出現XmlNode型別,VS2008究竟是依據什麼鬼,自作聰明跑出XmlNode來?

經過地毯式搜索,找出問題來了--App_Code下被放了一個同名的.wsdl檔,裡面的參數型別正是XmlNode!! 我這也才了解,原來不只App_WebReferences下的.wsdl檔案會被拿來產生Proxy Class,放在App_Code裡的.wsdl也會。當初不夠細心,沒注意同事在呼叫Proxy Class時未指定Namespace,因此實際呼叫的是放在App_Code下wsdl所產生,名稱相同且沒有Namespace的Class,當Proxy Class的參數宣告與Web Service不符時,便產生了Bad Request的錯誤。

最後待解的問題是,這個搗蛋的wsdl是從哪裡冒出來的? 詢問過關係人後真相大白--另一位同事之前Reference過該Web Service的舊版本,舊版參數用的是XmlNode型別,而參照舊版Web Service產生的wsdl因不可考的原因被搬到App_Code下,隨著整個專案一起複製給另一位同事改寫,結果遇上忘了加Namespace的狀況,兩個巧合搞出了今天的奇案。

報告完畢!


Comments

Be the first to post a comment

Post a comment