工作筆記 | Visual Studio 調用 Web Service


引言

最近筆者負責ERP財務系統跟中糧集團財務公司的財務系統做對接,鑒於ERP系統中應付結算單結算量比較大,而且管理相對集中,ERP系統與中糧財務公司的支付平台系統對接,實現銀企直聯,將網銀錄入的環節、付款以后ERP確認環節自動化,節省人工操作環節帶來的誤差。
這樣公司財務人員在我們的系統中做對外的付款單,自動向集團財務系統發起付款指令,由集團統一通過銀行給對應的供應商轉賬,並監控付款單的狀態,完成供應商在系統的正常結算。

系統對接環境

業務層面不再多述,本文主要介紹技術層面實施:

  • 集團財務公司提供的是基於SAP架構的Web Service接口
  • ERP開發環境使用VS2013
  • 訪問模式是半雙工,我們ERP系統單向遠程調用接口,發起付款指令、並輪詢付款單狀態

自VS2008以后,為了對.NET Framework 3.0 或 3.5版本上WCF Service Library的支持。增加了Add Service Reference(添加服務引用)功能,這樣可以在VS中很方便的添加Web Service接口引用,並通過簡單的配置,調用遠程服務。

申請開通集團通道白名單

一般來說不可以隨便訪問集團SAP,必須找運維人員開通訪問權限。開通后,通過telnet查看ip地址和端口是否已經開放,或者瀏覽器訪問,正常的話應該如下圖:
avatar

項目中添加服務引用

選中項目,右鍵 -> Add -> Service Reference
avatar
彈出的界面中,Address輸入提供的Web Service地址,然后點擊 GO 按鈕,這里一般會提示輸入用戶名和密碼,輸入后可以看到Web Service引用連通。展開服務,可以看到接口提供了2個方法。如果這一步提示錯誤,可以在瀏覽器中輸入地址,看看是否能訪問,其實就是訪問遠程的wsdl文件,如果訪問不了,再檢查是否是網絡或者權限的原因。
avatar
我們點“確定”,可以看到VS自動幫我們在項目目錄下生成了一個文件夾:Service References,里面有剛才看到的服務名,同時會在 app.config 中增加一段配置類似如下(如果當前沒有app.config文件,會自動生成):

  <system.serviceModel>
    <client>
      <endpoint address="http://xx.xx.xxx.xx:50000/xxxxxxx"
        binding="basicHttpBinding" bindingConfiguration="SOS_TxService_SendBinding"
        contract="TxService.SOS_TxService_Send" name="HTTP_Port" />
    </client>
  </system.serviceModel>

VS幫我們做了什么

為了更好的學習,我們深入了解一下,VS幫我們都做了哪些工作。
項目新建的Service References目錄下的服務,在VS中是無法查看的,我們可以進入對應的目錄下,看看都生成了哪些文件:
avatar
首先可以看到,目錄下有個wsdl文件,大家應該都熟悉,這是用來定義和描述Web Service的,通過這個文件,就可以知道接口都提供了哪些方法,輸入參數類型和輸出結果格式。打開這個wsdl文件看一下,跟我們想象的一樣,原來,VS在引用服務訪問遠程wsdl文件的同時,在本地拷貝了一份。
接下來我們看一個后綴為 .cs 重要的文件,打開看下,這里面,VS幫我們生成了關於這個服務的接口和實現類。
avatar
這里最重要的,是幫我們生成了 SOS_TxService_SendClient 這個類,研究一下,發現已經實現了之前看到的Send、Send1兩個方法,並提供了對應的異步方法。
avatar
我們整理一下VS做的工作:

  1. 添加服務引用時,訪問遠程 wsdl 文件,並拷貝本地;
  2. 根據 wsdl 文件中的接口定義,定義調用端接口(比如Send,Send1);
  3. 定義代理服務 SendClient 類,繼承上述定義的調用端接口,並提供具體實現(實現Send,Send1);
  4. 定義和實現其他輔助類,比如 SendRequest,SendResponse;
  5. 生成 app.config 中相關配置;

到這里,聰明的你可能要問,既然VS已經幫我們生成了代理服務類 SendClient,而且類已經提供了接口方法的具體實現,現在是不是直接實例化一個服務類,直接調用方法就可以遠程調用?是的,沒錯!VS基本把需要做的工作都幫你做了,剩下的就是使用就行了,簡單吧。

其他相關配置

一般情況下,我們訪問Web Service,需要提供用戶名和密碼的權限認證,否則直接調用的話,會報錯。
這里我們修改一下 app.config 文件如下:

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="SOS_TxService_SendBinding" >
          <security mode="TransportCredentialOnly" > 
            <transport clientCredentialType="Basic"/>           
            <message clientCredentialType="UserName"/>
          </security> 
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://xx.xx.xxx.xx:50000/xxxxxxx"
        binding="basicHttpBinding" bindingConfiguration="SOS_TxService_SendBinding"
        contract="TxService.SOS_TxService_Send" name="HTTP_Port" />
    </client>
  </system.serviceModel>

單元測試調用一下,可以看到能正常返回 xml 格式的結果:

[TestMethod]
public void WebServiceTest()
{
    var client = new SOS_TxService_SendClient();
    if (client.ClientCredentials != null)
    {
        client.ClientCredentials.UserName.UserName = "username";
        client.ClientCredentials.UserName.Password = "password";
        try
        {
            var tt = client.Send("test");
            Assert.IsTrue(tt.Length > 0);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}

還有一個問題,就是跨項目引用,比如在一個基礎服務項目中,實現了遠程調用。在應用層項目中,引用了基礎服務項目dll,應該注意以下一點:選中生成的服務,右鍵-> Configure Service Reference:
avatar
保證相關的程序集能夠正常引用,然后在應用層項目,並手動將 app.config 的相關配置拷貝至項目目錄下。

寫在最后

至此,我們通過VS調用 Web Service 實施成功,還是比較簡單,其實沒有什么技術難點,主要希望能深入了解原理,知道VS后台自動幫助我們做了哪些工作,如果我們不使用輔助工具的時候,要實現遠程訪問,應該怎么去實現。
注:目前 .net core 環境對 Web Service 支持不是很好,筆者在VS2017中,.net core 引用 Web Service依舊報錯,大家有興趣可以自己研究一下。


免責聲明!

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



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