勘誤表 - Visual Basic 2005 檔案 IO 與資料存取秘訣

摘要:勘誤表 - Visual Basic 2005 檔案 IO 與資料存取秘訣

我們在Visual Basic 2005 檔案 IO 與資料存取秘訣」一書之第章的 3-18.7 段落,探討了「如何繫結至一個Web Service。遺憾的是,程式範例 CH3_DemoForm039.vb 所繫結之 Web Service 的所屬網站(http://webservices.eraserver.net)不再提供任何服務,導致該程式範例無法正常運作。因此,我們採用了另外一個網站所提供的Web Service來示範如何繫結至一個 Web Service 

我們必須聲明,書中原先所撰寫的內容與技術邏輯完全正確,只是因為所使用的 Web Service 不再提供。改寫後的全文內容列示如下: 

3-18.7 如何繫結至一個Web Service

之前曾經提到過,當所要繫結的物件並不存在時,我們可以繫結至一個型別。正如大家所知道的,Web Service 所傳回的物件必須在執行階段才能取得,由此可以推知,繫結至一個 Web Service 的程序將會類似於繫結至一個型別。同樣的,我們仍舊應該使用 BindingSource 元件作為一個中間階層,如此一來,才能夠更方便將控制項繫結至一個 Web Service 所傳回的結果。 

欲繫結至一個 Web Service,您必須建立一個用戶端 Proxy 類別來內含 Web Service 所公開的方法與型別。用戶端 Proxy 類別可以由Web Service.asmx)本身來產生,或是由它的 Web 服務描述語言(WSDL)檔來產生。此外,用戶端 Proxy 類別必須將Web Service所使用的複雜型別之欄位公開成公用屬性,然後將 BindingSource 元件繫結至 Web Service Proxy 類別中所公開的其中一個屬性。 

在稍後的程式範例中,我們將逐步解說如何繫結至一個 Web Service 

 

 


圖表
3-71
 

程式範例 

圖表 3-71 所示者是程式範例 CH3_DemoForm039.vb 的執行畫面,它示範如何透過 BindingSource 元件將表單上的 TextBox 控制項繫結 Web Service CityStateContent 屬性。接下來,我們要詳述這一個程式碼範例的製作步驟,從中您將瞭解如何繫結至一個 Web Service 

請注意:
我們無法保證網站 http://innergears.com/WebServices3/CityStateByZip永遠不會關站或是它所提供的網路服務 CityStateByZip 永遠可以使用,特此聲明之。 

1.       首先,請替您的 Windows 應用程式專案加入對 System.Web.Services.dll 這一個組件的參考(如圖表 3-72 所示)。 

 


圖表
3-72
 

2.       接下來,請建立一個新的表單,並於表單上加入 BindingSource 元件、Label 控制項、TextBox 控制項、以及 Button 控制項,適當調整它們的屬性與外觀,使其如圖表 3-73 所示。 

 


圖表
3-73

 

3.       如圖表 3-74 所示,開啟Visual Studio 2005命令提示字元」並切換至表單所在的目錄。 

 


圖表
3-74
 

4.       現在我們要執行一項非常重要的操作,那就是使用Web 服務描述語言公用程式」(wsdl.exe來產生一個用戶端Proxy類別,以便於其中公開 Web Service 的方法與型別。本程式範例所使用的 Web Service 位於http://ws.strikeiron.com/InnerGears/CityStateByZip2?WSDL,因此請您於Visual Studio 2005命令提示字元」鍵入:

wsdl http://ws.strikeiron.com/InnerGears/CityStateByZip2?WSDL /language:VB

如圖表 3-75 所示,此舉會產生一個檔案來內含用戶端Proxy類別。請您切換回 Visual Studio 2005 的整合式開發環境,按一下「方案總管」之工具列中的「重新整理」按鈕,然後將剛剛所產生的用戶端 Proxy 類別檔新增至專案中(如圖表 3-76 所示)。 

 


圖表
3-75
 

 


圖表
3-76
 

5.       產生了用戶端 Prox y類別之後,接下來的工作,就是去完成各項繫結作業。我們必須將 BindingSource 元件繫結至用戶端 Proxy 類別中的某一個型別,此型別通常是 Web Service 之某一個方法的傳回值型別。您所要繫結之型別的欄位必須被公開成公用屬性,而這些公用屬性將成為控制項的繫結對象。

以本程式範例而言,我們要將 BindingSource 元件繫結至自訂的 CityState 型別。如下所示,CityState 型別會將各個欄位公開成公用屬性,其中的 CityStateContent 屬性即是表單上之 TextBox 控制項所要繫結的對象:

Public Class CityState
    Private _CityStateArray(1) As String
    Public Sub New(ByVal CityStateArray() As String)
        CityStateArray.CopyTo(_CityStateArray, 0)
    End Sub
    Public ReadOnly Property CityStateContent()
        Get
            Return _CityStateArray(0) & _CityStateArray(1)
        End Get
    End Property
End
Class

 

6.       現在請您於表單的 Load 事件處理常式中撰寫下列程式碼,以便將 BindingSource 元件繫結至 CityState 型別,並且將表單上 TextBox 控制項的 Text 屬性繫結至 CityState 型別所公開的公用屬性 CityStateContent

Private Sub CH3_DemoForm039_Load(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load

       
BindingSource1.DataSource = GetType(CityState)
        txtStateCity.DataBindings.Add("Text", Me.BindingSource1, _
          "CityStateContent", True)

   
End Sub
 

7.       請替「從 Web Service 取得州名及城市名稱」按鈕的 Click 事件處理常式撰寫下列程式碼,以便建立一個 CityStateByZip 執行個體、呼叫其 GetCityStateByZip 方法、並將 GetCityStateByZip 方法所傳回的 String 陣列型別指派給 CityState 類別建構函式,產生物件並新增至 BindingSource 元件的基礎清單中。特別要說明的是,LicenseInfo 類別與 UnregisteredUser 類別都是因應提供 Web Service 的廠商之要求,在每次叫用 Web Service 時所必須提供之資訊,有關更進一步的內容,請您參考提供服務廠商之說明: 

Private Sub btnGetZipCode_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles btnGetZipCode.Click

  '
顯示一個狀態訊息對話方塊來表示我們目前要嘗試連結至 Web Service
  Dim frmStatusMessage As frmStatus = New frmStatus

  frmStatusMessage.Show("
正在從Web Service 取得資料中....")

  Try
      Dim myLicenseInfo As LicenseInfo = New LicenseInfo
      Dim IamUnregisteredUser As UnregisteredUser = New UnregisteredUser
      Dim myCityStateByZip As CityStateByZip = New CityStateByZip

      '
產生叫用 Web 服務之使用者資訊內容。
      IamUnregisteredUser.EmailAddress = "xxx@yahoo.com.tw"
      myLicenseInfo.UnregisteredUser = IamUnregisteredUser
      myCityStateByZip.LicenseInfoValue = myLicenseInfo

      BindingSource1.Add(New _
         CityState(myCityStateByZip.GetCityStateByZip(txtZip.Text)))

  Catch ex As Exception
      MessageBox.Show(ex.Message)
  End Try
  frmStatusMessage.Close()
End Sub