記一次.net core調用SOAP接口遇到的問題


背景

       最近需要將一些外部的Web Service及其他SOAP接口的調用移到一個獨立的WebAPI項目中,然后供其他.Net Core項目調用。之前的幾個Web Service已經成功遷移,但是在遷移一個需要用戶名密碼認證的SOAP接口的時候卻始終調用不成功。下面直接上代碼。

示例代碼

.net framework中通過添加服務引用會自動在web.config(或者app.config)中生成類似以下綁定配置:

<system.serviceModel>
  <bindings>
    <customBinding>
      <binding name="binding">
        <mtomMessageEncoding ="Soap11WSAddressing10" />
        <httpTransport authenticationScheme="Basic"/>
      </binding>
    </customBinding>
  </bindings>
  <client>
    <endpoint address="http://sampl.url" binding="customBinding" bindingConfiguration="binding" contract="TestClient" name="binding" />
  </client>
</system.serviceModel>

可以直接調用client的無參構造函數(會從配置中讀取相應的配置)來獲取客戶端實例,但是由於.net core中已經不支持web.config(或者app.config),因此需要自己通過代碼來創建bindingEndpointAddress來獲取客戶端實例

var binding = new CustomBinding(new HttpTransportBindingElement
{
    AuthenticationScheme = AuthenticationSchemes.Basic
});

var client = new TestClient(binding, new EndpointAddress(new Uri("http://sample.url")));
client.ClientCredentials.UserName.UserName = "admin";
client.ClientCredentials.UserName.Password = "123456";

var response = client.Add(new Request()).Result

發現問題

      在測試過程中始終拋異常The server returned an invalid or unrecognized response.。使用上面相同的代碼在.net framework里測試卻能正常獲取響應,初步判斷應該是.net core中的問題。通過wireshark工具抓包比對,我發現了差別。

請求正常的抓包截圖
成功

請求失敗的抓包截圖
失敗

通過兩個請求的比對發現,失敗的請求頭部信息中沒有Authorization信息。接着我使用HttpClient發送post請求來模擬對SOAP接口的調用。


httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "YWRtaW46MTIzNDU2==");

在設置和不設置Authorization的分別測試中發現設置了Authorization能夠成功請求並獲得響應,不設置Authorization的請求獲得了一段html格式的文本響應,其中有一段很說明問題HTTP 401 - Unauthorized。在這兩個不同的請求抓包中也發現成功的請求頭部中是包含Authorization信息的,另一個則沒有。因此基本斷定問題就出現在這里。

如何解決

      問題找到了,是因為請求頭部中缺少Authorization信息,但是如何解決我卻始終沒有找到好的辦法,SOAP接口的調用不像使用HttpClient發送post請求可以對header進行修改。直接使用HttpClient發送post請求來調用SOAP接口對XML的序列化和反序列化又很是麻煩,也不想使用這種過於牽強的做法。翻遍了博客園和stackoverfolw也始終沒有找到解決辦法。

      終於,在我不懈的努力中看到了曙光,在github上翻dotnet/wcfIssues的時候找到一些相關東西,特別是這一條https://github.com/dotnet/wcf/issues/3008。其中提到System.Private.ServiceModel版本高於或等於4.5.0的時候會拋異常The server returned an invalid or unrecognized response.,雖然他的使用跟我的不太一樣,但是異常信息卻相同。我當即將版本降到4.4.4再次測試,結果令人驚喜,請求成功了,通過抓包分析Authorization信息在請求頭部中。這證實我之前的判斷,就是因為沒有Authorization信息導致請求失敗。

結語

      問題解決了,System.Private.ServiceModel4.5.0及以上版本會存在此問題,降級到4.4.4方可解決,希望微軟早日修復此問題,在NuGet包管理中看到有更新但又不能更新的包是一件很不爽的事情!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM