逐步解說:使用用戶端應用程式服務

這個主題描述如何建立使用用戶端應用程式服務的 Windows 應用程式,以驗證使用者並擷取使用者角色與設定。

在這個逐步解說中,您會執行下列工作:

  • 建立 Windows Form 應用程式,並且使用 Visual Studio 專案設計工具啟用與設定用戶端應用程式服務。

  • 建立簡單的 ASP.NET Web Service 應用程式,以裝載應用程式服務並且測試用戶端組態。

  • 將表單驗證加入至應用程式。 一開始會使用硬式編碼的使用者名稱與密碼測試服務。 然後將登入表單指定為應用程式組態中的認證提供者予以加入。

  • 加入以角色為基礎的功能,並且只針對具有「管理員」角色的使用者啟用與顯示按鈕。

  • 存取 Web 設定。 一開始會在專案設計工具的 [設定] 頁面中載入已驗證 (測試) 使用者的 Web 設定。 然後使用 Windows Form 設計工具將文字方塊繫結至 Web 設定。 最後再將已修改的值儲存回伺服器。

  • 實作登出。 您會將登出選項加入至表單,然後呼叫登出方法。

  • 啟用離線模式。 您會提供核取方塊供使用者指定其連接狀態。 然後使用此值指定用戶端應用程式服務提供者,是否使用本機快取資料而不是存取其 Web 服務。 最後當應用程式返回線上模式時,再重新驗證目前的使用者。

必要條件

您需要下列元件才能完成此逐步解說:

  • Visual Studio 2008。

建立用戶端應用程式。

首先您要做的是建立 Windows Form 專案。 這個逐步解說會使用 Windows Form,因為很多人已熟悉這項功能,而且程序類似 Windows Presentation Foundation (WPF) 專案。

建立用戶端應用程式並啟用用戶端應用程式服務

  1. 在 Visual Studio 中選取 [檔案 | 新增 | 專案] 功能表選項。

  2. 在 [新增專案] 對話方塊中,請展開 [專案類型] 窗格中的 [Visual Basic] 或 [Visual C#] 節點,然後選取 [Windows] 專案類型。

  3. 請確定已選取 [.NET Framework 3.5],然後選取 [Windows Form 應用程式] 範本。

  4. 將專案的 [名稱] 變更為 ClientAppServicesDemo,然後按一下 [確定]。

    在 Visual Studio 中隨即開啟新的 Windows Form 專案。

  5. 在 [專案] 功能表上,選取 [ClientAppServicesDemo 屬性]。

    [專案設計工具] 隨即出現。

  6. 在 [服務] 索引標籤上,選取 [啟用用戶端應用程式服務]。

  7. 請確定已選取 [使用表單驗證],然後將 [驗證服務位置]、[角色服務位置] 以及 [Web 設定服務位置] 設定為 https://localhost:55555/AppServices。

  8. 在 Visual Basic 的 [應用程式] 索引標籤中,將 [驗證模式] 設定為 [由應用程式定義]。

設計工具會將指定的設定儲存在應用程式的 app.config 檔中。

此時,應用程式會設定為從相同的主機存取這三種服務。 在下一章節,將建立當做簡單 Web 服務應用程式的主機,以便讓您測試用戶端組態。

建立應用程式服務主機

在此章節中,您將建立簡單的 Web 服務應用程式,以便從本機 SQL Server Compact 3.5 資料庫檔案存取使用者資料。 接著,您將會使用 ASP.NET 網站管理工具填入資料庫。 此簡單的組態可讓您快速地測試用戶端應用程式。 除此之外,您還可以設定 Web 服務主機,以便從完整的 SQL Server 資料庫存取使用者資料,或透過自訂 MembershipProviderRoleProvider 類別來存取使用者資料。 如需詳細資訊,請參閱 建立及設定 SQL Server 的應用程式服務資料庫

在下列程序中,將建立與設定 AppServices Web 服務。

建立與設定應用程式服務主機

  1. 在 [方案總管] 中,選取 ClientAppServicesDemo 方案,然後在 [檔案] 功能表上選取 [加入 | 新增專案]。

  2. 在 [加入新的專案] 對話方塊中,請展開 [專案類型] 窗格中的 [Visual Basic] 或 [Visual C#] 節點,然後選取 [Web] 專案類型。

  3. 請確定已選取 [.NET Framework 3.5],然後選取 [ASP.NET Web Service 應用程式] 範本。

  4. 將專案的 [名稱] 變更為 AppServices,然後按一下 [確定]。

    新的 ASP.NET Web 服務應用程式專案隨即加入至方案,而編輯器中會出現 Service1.asmx.vb 或 Service1.asmx.cs 檔案。

    注意事項注意事項

    本範例中不會使用 Service1.asmx.vb 或 Service1.asmx.cs 檔案。 如果您想要保持工作環境的整齊,可以將其關閉,並將其從 [方案總管] 中刪除。

  5. 在 [方案總管] 中選取 AppServices 專案,然後在 [專案] 功能表上選取 [AppServices 屬性]。

    [專案設計工具] 隨即出現。

  6. 在 [Web] 索引標籤上,請確定已選取 [使用 Visual Studio 程式開發伺服器]。

  7. 選取 [指定通訊埠],指定值為 55555,然後將 [虛擬路徑] 設定為 /AppServices。

  8. 儲存所有檔案。

  9. 在 [方案總管] 中,開啟 Web.config 然後尋找 <system.web> 開頭標記。

  10. 在 <system.web> 標記 (Tag) 之前加入下列標記 (Markup)。

    在這個標記中的 authenticationService、profileService 以及 roleService 項目會啟用與設定應用程式服務。 基於測試目的,authenticationService 項目的 requireSSL 屬性會設定為 "false"。 profileService 項目的 readAccessProperties 和 writeAccessProperties 屬性 (Attribute) 表示 WebSettingsTestText 屬性 (Property) 是讀取/寫入。

    注意事項注意事項

    在實際執行程式碼中,一定要透過 Secure Sockets Layer (SSL,使用 HTTPS 通訊協定) 存取驗證服務。 如需設定 SSL 的詳細資訊,請參閱設定 Secure Sockets Layer (IIS 6.0 操作手冊) (英文)。

    <system.web.extensions>
      <scripting>
        <webServices>
          <authenticationService enabled="true" requireSSL = "false"/>
          <profileService enabled="true"
            readAccessProperties="WebSettingsTestText"
            writeAccessProperties="WebSettingsTestText" />
          <roleService enabled="true"/>
        </webServices>
      </scripting>
    </system.web.extensions>
    
  11. 在 <system.web> 開頭標記 (Tag) 之後加入下列標記 (Markup),將其包含在 <system.web> 項目中。

    profile 項目會設定名為 WebSettingsTestText 的單一 Web 設定。

    <profile enabled="true" >
      <properties>
        <add name="WebSettingsTestText" type="string" 
          readOnly="false" defaultValue="DefaultText" 
          serializeAs="String" allowAnonymous="false" />
      </properties>
    </profile>
    

在下列程序中,您會使用 [ASP.NET 網站管理工具] 來完成服務組態及填入本機資料庫檔案。 您將新增兩個名為 employee 和 manager 的使用者,屬於兩個名稱相同的角色。 使用者密碼分別為 employee! 和 manager!。

若要設定成員資格和角色

  1. 在 [方案總管] 中選取 [AppServices] 專案,然後在 [專案] 功能表上選取 [ASP.NET 組態]。

    [ASP.NET 網站管理工具] 隨即出現。

  2. 按一下 [安全性] 索引標籤上的 [使用安全性設定精靈,逐步設定安全性]。

    [安全性設定精靈] 隨即出現,並顯示 [歡迎使用] 步驟。

  3. 按一下 [下一步]。

    [選取存取方法] 步驟隨即出現。

  4. 選取 [從網際網路]。 此步驟會將服務設定為使用表單驗證,而不是 Windows 驗證。

  5. 按 [下一步] 兩次。

    [定義角色] 步驟隨即出現。

  6. 選取 [啟用這個網站的角色]。

  7. 按一下 [下一步]。 [建立新角色] 表單隨即出現。

  8. 在 [新角色名稱] 文字方塊中輸入 manager,然後按一下 [加入角色]。

    具有指定值的 [現有角色] 資料表隨即出現。

  9. 在 [新角色名稱] 文字方塊中,以 employee 取代 manager,然後按一下 [加入角色]。

    [現有角色] 資料表中隨即出現新的值。

  10. 按一下 [下一步]。

    [加入新的使用者] 步驟隨即出現。

  11. 在 [建立使用者] 表單中,指定下列值。

    使用者名稱

    manager

    密碼

    manager!

    確認密碼

    manager!

    電子郵件

    manager@contoso.com

    安全性問題

    manager

    安全性解答

    manager

  12. 按一下 [建立使用者]。

    成功訊息隨即出現。

    注意事項注意事項

    [電子郵件]、[安全性問題] 和 [安全性解答] 是表單的必填欄位,但此例中並未使用。

  13. 按一下 [繼續]。

    [建立使用者] 表單隨即重新出現。

  14. 在 [建立使用者] 表單中,指定下列值。

    使用者名稱

    employee

    密碼

    employee!

    確認密碼

    employee!

    電子郵件

    employee@contoso.com

    安全性問題

    Employee

    安全性解答

    employee

  15. 按一下 [建立使用者]。

    成功訊息隨即出現。

  16. 按一下 [完成]。

    [網站管理工具] 隨即重新出現。

  17. 按一下 [管理使用者]。

    使用者清單隨即出現。

  18. 針對 [employee] 使用者按一下 [編輯角色],然後選取 [employee] 角色。

  19. 針對 [manager] 使用者按一下 [編輯角色],然後選取 [manager] 角色。

  20. 關閉裝載 (Host) [網站管理工具] 的瀏覽器視窗。

  21. 如果出現訊息方塊,詢問您是否要重新載入修改後的 Web.config 檔案,請按一下 []。

這就完成了 Web 服務的設定。 此時,您可以按 F5 執行用戶端應用程式,然後 [ASP.NET 程式開發伺服器] 將會自動與用戶端應用程式一起啟動。 在您結束應用程式後,伺服器會繼續執行,但是會在重新啟動應用程式時重新啟動。 如此可以讓它偵測對 Web.config 所做的任何變更。

若要手動停止伺服器,以滑鼠右鍵按一下工作列上告知區域中的 ASP.NET 程式開發伺服器圖示,然後按一下 [停止]。 有時候在確定是否完全重新啟動時很有用。

加入表單驗證

在下列程序中,會在嘗試驗證使用者的主要表單中加入程式碼,並且在使用者提供無效認證時拒絕存取。 您會使用硬式編碼的使用者名稱與密碼測試服務。

在應用程式程式碼中驗證使用者

  1. 在 [方案總管] 中,於 ClientAppServicesDemo 專案中加入 System.Web 組件的參考。

  2. 選取 Form1 檔,然後從 Visual Studio 主功能表選取 [檢視 | 程式碼]。

  3. 在程式碼編輯器中,將下列陳述式加入至 Form1 檔的頂端。

    Imports System.Net
    Imports System.Threading
    Imports System.Web.ClientServices
    Imports System.Web.ClientServices.Providers
    Imports System.Web.Security
    
    using System.Net;
    using System.Threading;
    using System.Web.ClientServices;
    using System.Web.ClientServices.Providers;
    using System.Web.Security;
    
  4. 在 [方案總管] 中,按兩下 Form1 顯示設計工具。

  5. 在設計工具中,按兩下表單介面,產生名為 Form1_Load 的 Form.Load 事件處理常式。

    程式碼編輯器隨即出現,並將游標置於 Form1_Load 方法中。

  6. 將以下程式碼加入至 Form1_Load 方法中。

    這段程式碼會以結束應用程式的方式,拒絕未經驗證之使用者的存取。 此外,您也可以允許未經驗證之使用者存取表單,但是拒絕其存取特定功能。 通常您不會以這種方式硬式編碼使用者名稱與密碼,但是基於測試目的就很有用。 在下一章節中,您將會使用更強固的程式碼取代這段程式碼,以顯示登入對話方塊並包含例外狀況處理。

    請注意,static Membership.ValidateUser 方法是在 .NET Framework 2.0 版中。 這個方法會將其工作委派至已設定的驗證提供者,然後在驗證成功時傳回 true。 您的應用程式不需要直接參考用戶端驗證提供者。

    If Not Membership.ValidateUser("manager", "manager!") Then
    
        MessageBox.Show("Unable to authenticate.", "Not logged in", _
            MessageBoxButtons.OK, MessageBoxIcon.Error)
        Application.Exit()
    
    End If
    
    if (!Membership.ValidateUser("manager", "manager!"))
    {
        MessageBox.Show("Unable to authenticate.", "Not logged in",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
        Application.Exit();
    }
    

您現在可以按 F5 執行應用程式,並且由於提供了正確的使用者名稱與密碼,您將會看到表單出現。

注意事項注意事項

如果您無法執行應用程式,請嘗試停止 ASP.NET 程式開發伺服器。 當伺服器重新啟動時,請確認通訊埠是設定為 55555。

而若要看見錯誤訊息,請變更 ValidateUser 參數。 例如,以錯誤密碼取代第二個 "manager!" 參數,如 "MANAGER"。

加入登入表單當做認證提供者

您可以在應用程式程式碼中取得使用者認證,並將其傳遞至 ValidateUser 方法。 但是,通常將取得認證的程式碼與應用程式程式碼分開是很有用的,以方便後續想要予以變更。

在下列程序中,會將應用程式設定為使用認證提供者,然後變更您的 ValidateUser 方法呼叫,同時針對兩個參數傳遞 Empty。 空字串會對 ValidateUser 方法發出訊號,使其呼叫已設定之認證提供者的 GetCredentials 方法。

將應用程式設定為使用認證提供者

  1. 在 [方案總管] 中,選取 ClientAppServicesDemo 專案,然後在 [專案] 功能表上選取 [ClientAppServicesDemo 屬性]。

    [專案設計工具] 隨即出現。

  2. 在 [服務] 索引標籤中,將 [選擇性:認證提供者] 設定為下列值。 這個值表示組件限定的類型名稱。

    ClientAppServicesDemo.Login, ClientAppServicesDemo
    
  3. 在 Form1 程式碼檔案中,將 Form1_Load 方法中的程式碼以下列程式碼取代。

    這段程式碼會顯示歡迎訊息,然後呼叫在下一步驟會加入的 ValidateUsingCredentialsProvider 方法。 如果使用者未經過驗證,ValidateUsingCredentialsProvider 方法會傳回 false 並且傳回 Form1_Load 方法。 這可以避免在應用程式結束之前執行任何其他的程式碼。 歡迎訊息可以清楚表示應用程式重新啟動的時間。 當您在這個逐步解說稍後實作登出時,將會加入程式碼以重新啟動應用程式。

    MessageBox.Show("Welcome to the Client Application Services Demo.", _
        "Welcome!")
    
    If Not ValidateUsingCredentialsProvider() Then Return
    
    MessageBox.Show("Welcome to the Client Application Services Demo.",
        "Welcome!");
    
    if (!ValidateUsingCredentialsProvider()) return;
    
  4. 將下列方法加到 Form1_Load 方法之後。

    這個方法會將空字串傳遞至 static Membership.ValidateUser 方法,而出現 [登入] 對話方塊。 如果驗證服務無法使用,ValidateUser 方法將擲回 WebException。 在上述情形中,ValidateUsingCredentialsProvider 方法會顯示警告訊息,並詢問使用者是否要在離線模式再次嘗試。 這項功能需要在 HOW TO:設定用戶端應用程式服務中所描述的 [在本機儲存密碼雜湊以啟用離線登入] 功能。 新專案預設會啟用這項功能。

    如果使用者並未經過驗證,ValidateUsingCredentialsProvider 方法會顯示錯誤訊息並結束應用程式。 最後,這個方法會傳回驗證嘗試的結果。

    Private Function ValidateUsingCredentialsProvider() As Boolean
    
        Dim isAuthorized As Boolean = False
    
        Try
    
            ' Call ValidateUser with empty strings in order to display the 
            ' login dialog box configured as a credentials provider.
            isAuthorized = Membership.ValidateUser( _
                String.Empty, String.Empty)
    
        Catch ex As System.Net.WebException
    
            If DialogResult.OK = MessageBox.Show( _
                "Unable to access the authentication service." & _
                Environment.NewLine & "Attempt login in offline mode?", _
                "Warning", MessageBoxButtons.OKCancel, _
                MessageBoxIcon.Warning) Then
    
                ConnectivityStatus.IsOffline = True
                isAuthorized = Membership.ValidateUser( _
                    String.Empty, String.Empty)
    
            End If
    
        End Try
    
        If Not isAuthorized Then
    
            MessageBox.Show("Unable to authenticate.", "Not logged in", _
                MessageBoxButtons.OK, MessageBoxIcon.Error)
            Application.Exit()
    
        End If
    
        Return isAuthorized
    
    End Function
    
    private bool ValidateUsingCredentialsProvider()
    {
        bool isAuthorized = false;
        try
        {
            // Call ValidateUser with empty strings in order to display the 
            // login dialog box configured as a credentials provider.
            isAuthorized = Membership.ValidateUser(
                String.Empty, String.Empty);
        }
        catch (System.Net.WebException)
        {
            if (DialogResult.OK == MessageBox.Show(
                "Unable to access the authentication service." +
                Environment.NewLine + "Attempt login in offline mode?",
                "Warning", MessageBoxButtons.OKCancel, 
                MessageBoxIcon.Warning))
            {
                ConnectivityStatus.IsOffline = true;
                isAuthorized = Membership.ValidateUser(
                    String.Empty, String.Empty);
            }
        }
    
        if (!isAuthorized)
        {
            MessageBox.Show("Unable to authenticate.", "Not logged in",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            Application.Exit();
        }
        return isAuthorized;
    }
    

建立登入表單

認證提供者是實作 IClientFormsAuthenticationCredentialsProvider 介面的類別。 這個介面有個名為 GetCredentials 的單一方法,可傳回 ClientFormsAuthenticationCredentials 物件。 下列程序描述如何建立實作 GetCredentials 的登入對話方塊,以顯示本身並且傳回使用者指定的認證。

對 Visual Basic 和 C# 會提供不同的程序,因為 Visual Basic 會提供 [登入表單] 範本。 這可以節省一些時間與撰寫程式碼的人力。

建立登入對話方塊當做 Visual Basic 中的認證提供者

  1. 在 [方案總管] 中,選取 ClientAppServicesDemo 專案,然後在 [專案] 功能表上選取 [加入新項目]。

  2. 在 [加入新項目] 對話方塊中,選取 [登入表單] 範本,將項目 [名稱] 變更為 Login.vb,然後按一下 [加入]。

    登入對話方塊就會出現在 [Windows Form 設計工具] 中。

  3. 在設計工具中,選取 [確定] 按鈕,然後在 [屬性] 視窗中將 DialogResult 設定為 OK。

  4. 在設計工具中,將 CheckBox 控制項加入至 [密碼] 文字方塊下的表單中。

  5. 在 [屬性] 視窗中,將 [(Name)] 值指定為 rememberMeCheckBox,並且將 [Text] 值指定為 &Remember me。

  6. 從 Visual Studio 主功能表選取 [檢視 | 程式碼]。

  7. 在程式碼編輯器中,將下列程式碼加入至檔案的頂端。

    Imports System.Web.ClientServices.Providers
    
  8. 修改類別簽章以便讓類別實作 IClientFormsAuthenticationCredentialsProvider 介面。

    Public Class Login
        Implements IClientFormsAuthenticationCredentialsProvider
    
  9. 請確定游標在 IClientformsAuthenticationCredentialsProvider 後方,然後按 ENTER 產生 GetCredentials 方法。

  10. 找到 GetCredentials 實作,然後以下列程式碼取代。

    Public Function GetCredentials() As  _
        ClientFormsAuthenticationCredentials Implements _
        IClientFormsAuthenticationCredentialsProvider.GetCredentials
    
        If Me.ShowDialog() = DialogResult.OK Then
            Return New ClientFormsAuthenticationCredentials( _
                UsernameTextBox.Text, PasswordTextBox.Text, _
                rememberMeCheckBox.Checked)
        Else
            Return Nothing
        End If
    
    End Function
    

下列 C# 程序提供簡單登入對話方塊的完整程式碼清單。 這個對話方塊的配置有一點粗糙,但是重點是 GetCredentials 實作。

建立登入對話方塊當做 C# 中的認證提供者

  1. 在 [方案總管] 中選取 ClientAppServicesDemo 專案,然後在 [專案] 功能表上選取 [加入類別]。

  2. 在 [加入新項目] 對話方塊中,將 [名稱] 變更為 Login.cs,然後按一下 [加入]。

    Login.cs 檔會在程式碼編輯器中開啟。

  3. 請用下列程式碼取代預設程式碼。

    using System.Windows.Forms;
    using System.Web.ClientServices.Providers;
    
    namespace ClientAppServicesDemo
    {
        class Login : Form,
            IClientFormsAuthenticationCredentialsProvider
        {
            private TextBox usernameTextBox;
            private TextBox passwordTextBox;
            private CheckBox rememberMeCheckBox;
            private Button OK;
            private Button cancel;
            private Label label1;
            private Label label2;
    
            public ClientFormsAuthenticationCredentials GetCredentials()
            {
                if (this.ShowDialog() == DialogResult.OK)
                {
                    return new ClientFormsAuthenticationCredentials(
                        usernameTextBox.Text, passwordTextBox.Text,
                        rememberMeCheckBox.Checked);
                }
                else
                {
                    return null;
                }
            }
    
            public Login()
            {
                InitializeComponent();
            }
    
            private void CloseForm(object sender, System.EventArgs e)
            {
                this.Close();
            }
    
            private void InitializeComponent()
            {
                this.label1 = new System.Windows.Forms.Label();
                this.usernameTextBox = new System.Windows.Forms.TextBox();
                this.label2 = new System.Windows.Forms.Label();
                this.passwordTextBox = new System.Windows.Forms.TextBox();
                this.rememberMeCheckBox = new System.Windows.Forms.CheckBox();
                this.OK = new System.Windows.Forms.Button();
                this.cancel = new System.Windows.Forms.Button();
                this.SuspendLayout();
                // 
                // label1
                // 
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(13, 13);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(58, 13);
                this.label1.TabIndex = 0;
                this.label1.Text = "&User name";
                // 
                // usernameTextBox
                // 
                this.usernameTextBox.Location = new System.Drawing.Point(13, 30);
                this.usernameTextBox.Name = "usernameTextBox";
                this.usernameTextBox.Size = new System.Drawing.Size(157, 20);
                this.usernameTextBox.TabIndex = 1;
                // 
                // label2
                // 
                this.label2.AutoSize = true;
                this.label2.Location = new System.Drawing.Point(13, 57);
                this.label2.Name = "label2";
                this.label2.Size = new System.Drawing.Size(53, 13);
                this.label2.TabIndex = 2;
                this.label2.Text = "&Password";
                // 
                // passwordTextBox
                // 
                this.passwordTextBox.Location = new System.Drawing.Point(13, 74);
                this.passwordTextBox.Name = "passwordTextBox";
                this.passwordTextBox.PasswordChar = '*';
                this.passwordTextBox.Size = new System.Drawing.Size(157, 20);
                this.passwordTextBox.TabIndex = 3;
                // 
                // rememberMeCheckBox
                // 
                this.rememberMeCheckBox.AutoSize = true;
                this.rememberMeCheckBox.Location = new System.Drawing.Point(13, 101);
                this.rememberMeCheckBox.Name = "rememberMeCheckBox";
                this.rememberMeCheckBox.Size = new System.Drawing.Size(94, 17);
                this.rememberMeCheckBox.TabIndex = 4;
                this.rememberMeCheckBox.Text = "&Remember me";
                this.rememberMeCheckBox.UseVisualStyleBackColor = true;
                // 
                // OK
                // 
                this.OK.DialogResult = System.Windows.Forms.DialogResult.OK;
                this.OK.Location = new System.Drawing.Point(13, 125);
                this.OK.Name = "OK";
                this.OK.Size = new System.Drawing.Size(75, 23);
                this.OK.TabIndex = 5;
                this.OK.Text = "&OK";
                this.OK.UseVisualStyleBackColor = true;
                // 
                // cancel
                // 
                this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
                this.cancel.Location = new System.Drawing.Point(95, 125);
                this.cancel.Name = "cancel";
                this.cancel.Size = new System.Drawing.Size(75, 23);
                this.cancel.TabIndex = 6;
                this.cancel.Text = "&Cancel";
                this.cancel.UseVisualStyleBackColor = true;
                // 
                // Login
                // 
                this.AcceptButton = this.OK;
                this.CancelButton = this.cancel;
                this.ClientSize = new System.Drawing.Size(187, 168);
                this.Controls.Add(this.cancel);
                this.Controls.Add(this.OK);
                this.Controls.Add(this.rememberMeCheckBox);
                this.Controls.Add(this.passwordTextBox);
                this.Controls.Add(this.label2);
                this.Controls.Add(this.usernameTextBox);
                this.Controls.Add(this.label1);
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
                this.MaximizeBox = false;
                this.MinimizeBox = false;
                this.Name = "Login";
                this.Text = "Login";
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
        }
    
    }
    

您現在可以執行應用程式,然後會看到登入對話方塊出現。 若要測試這段程式碼,請同時嘗試有效與無效的不同認證,然後確認您只能夠以有效認證存取表單。 有效的使用者名稱為 employee 和 manager,其密碼分別為 employee! 和 manager!。

注意事項注意事項

請勿在此時選取 [儲存我的資訊],否則在此逐步解說稍後實作登出之前,您都將無法以其他使用者登入。

加入以角色為基礎的功能

在下列程序中,您會將按鈕加入表單並且只讓具有管理員角色的使用者檢視。

根據使用者角色變更使用者介面

  1. 在 [方案總管] 中的 ClientAppServicesDemo 專案中選取 Form1,然後選取 Visual Studio 主功能表中的 [檢視 | 設計工具]。

  2. 在設計工具中,從 [工具箱] 將 Button 控制項加入至表單。

  3. 在 [屬性] 視窗中,設定按鈕的下列屬性。

    屬性

    (名稱)

    managerOnlyButton

    Text

    &Manager task

    Visible

    False

  4. 在 Form1 的程式碼編輯器中,將下列程式碼加入至 Form1_Load 方法的結尾。

    這段程式碼會呼叫將在下一個步驟加入的 DisplayButtonForManagerRole 方法。

    DisplayButtonForManagerRole()
    
    DisplayButtonForManagerRole();
    
  5. 在 Form1 類別結尾處加入下列方法。

    這個方法會呼叫 static Thread.CurrentPrincipal 屬性所傳回之 IPrincipalIsInRole 方法。 針對設定為使用用戶端應用程式服務的應用程式,這個屬性會傳回 ClientRolePrincipal。 因為這個類別會實作 IPrincipal 介面,所以您不需要明確地參考它。

    如果使用者具有 "manager" 角色,DisplayButtonForManagerRole 方法會將 managerOnlyButton 的 Visible 屬性設定為 true。 如果擲回 WebException 表示角色服務無法使用,這個方法也會顯示錯誤訊息。

    注意事項注意事項

    如果使用者登入已經逾期,IsInRole 方法就一定會傳回 false。 如果應用程式在驗證後很短的時間內呼叫一次 IsInRole 方法,如本逐步解說的範例程式碼所示,則不會發生這種情況。 如果應用程式必須在其他時間點擷取使用者角色,您就可能會想要加入程式碼,以重新驗證登入逾期的使用者。 如果所有有效的使用者都指派給角色,您可以呼叫 ClientRoleProvider.GetRolesForUser 方法以判斷登入是否過期。 如果沒有角色傳回,表示登入已經過期。 如需這項功能的範例,請參閱 GetRolesForUser 方法。 只有在應用程式組態中已選取 [要求使用者在伺服器 Cookie 過期時必須再次登入] 的情況下才需要這項功能。 如需詳細資訊,請參閱 HOW TO:設定用戶端應用程式服務

    Private Sub DisplayButtonForManagerRole()
    
        Try
    
            If Thread.CurrentPrincipal.IsInRole("manager") Then
    
                managerOnlyButton.Visible = True
    
            End If
    
        Catch ex As System.Net.WebException
    
            MessageBox.Show("Unable to access the roles service.", _
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    
        End Try
    
    End Sub
    
    private void DisplayButtonForManagerRole()
    {
        try
        {
            if (Thread.CurrentPrincipal.IsInRole("manager"))
            {
                managerOnlyButton.Visible = true;
            }
        }
        catch (System.Net.WebException)
        {
            MessageBox.Show("Unable to access the role service.",
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    

如果驗證成功,用戶端驗證提供者會將 Thread.CurrentPrincipal 屬性設定為 ClientRolePrincipal 類別的執行個體。 這個類別會實作 IsInRole 方法,以便讓工作委派至已設定的角色提供者。 跟先前一樣,應用程式程式碼不需要直接參考服務提供者。

您現在可以執行應用程式並且以 employee 身分登入,您會發現按鈕並未顯示,然後使用 manager 身分登入則會看到按鈕。

存取 Web 設定

在下列程序中,您會將文字方塊加入至表單並繫結至 Web 設定。 如同先前使用驗證與角色的程式碼,您的設定程式碼不會直接存取設定提供者。 反而會使用 Visual Studio 針對專案所產生的強型別 Settings 類別 (在 C# 中是當做 Properties.Settings.Default 存取,而在 Visual Basic 中則是當做 My.Settings 存取)。

在使用者介面中使用 Web 設定

  1. 請檢查工作列的告知區域,以確定 [ASP.NET Web 程式開發伺服器] 仍在執行中。 如果您已經停止伺服器,請重新啟動應用程式 (這會自動啟動伺服器) 然後關閉登入對話方塊。

  2. 在 [方案總管] 中,選取 ClientAppServicesDemo 專案,然後在 [專案] 功能表上選取 [ClientAppServicesDemo 屬性]。

    [專案設計工具] 隨即出現。

  3. 在 [設定] 索引標籤上,按一下 [載入 Web 設定]。

    [登入] 對話方塊隨即出現。

  4. 輸入 employee 或 manager 的認證,然後按一下 [登入]。 您將使用的 Web 設定是設定為只有經過驗證的使用者才能存取,因此按一下 [略過登入] 將不會載入任何設定。

    WebSettingsTestText 設定會以 DefaultText 的預設值出現在設計工具中。 此外,也會為專案產生包含了 WebSettingsTestText 屬性的 Settings 類別。

  5. 在 [方案總管] 中的 ClientAppServicesDemo 專案中選取 Form1,然後選取 Visual Studio 主功能表中的 [檢視 | 設計工具]。

  6. 在設計工具中,將 TextBox 控制項加入至表單。

  7. 在 [屬性] 視窗中,將 [(Name)] 值指定為 webSettingsTestTextBox。

  8. 在程式碼編輯器中,將下列程式碼加入至 Form1_Load 方法的結尾。

    這段程式碼會呼叫將在下一個步驟加入的 BindWebSettingsTestTextBox 方法。

    BindWebSettingsTestTextBox()
    
    BindWebSettingsTestTextBox();
    
  9. 在 Form1 類別結尾處加入下列方法。

    這個方法會將 webSettingsTestTextBox 的 Text 屬性,繫結至本程序稍早所產生之 Settings 類別的 WebSettingsTestText 屬性。 如果擲回 WebException 表示 Web 設定服務無法使用,這個方法也會顯示錯誤訊息。

    Private Sub BindWebSettingsTestTextBox()
    
        Try
    
            Me.webSettingsTestTextBox.DataBindings.Add("Text", _
                My.Settings, "WebSettingsTestText")
    
        Catch ex As WebException
    
            MessageBox.Show("Unable to access the Web settings service.", _
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    
        End Try
    
    End Sub
    
    private void BindWebSettingsTestTextBox()
    {
        try
        {
            this.webSettingsTestTextBox.DataBindings.Add("Text",
                Properties.Settings.Default, "WebSettingsTestText");
        }
        catch (WebException)
        {
            MessageBox.Show("Unable to access the Web settings service.",
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    
    注意事項注意事項

    您通常會使用資料繫結啟用控制項與 Web 設定之間的自動雙向通訊。 但是,您也可以直接存取 Web 設定,如同下列範例所示:

    webSettingsTestTextBox.Text = My.Settings.WebSettingsTestText
    
    webSettingsTestTextBox.Text =
        Properties.Settings.Default.WebSettingsTestText;
    
  10. 在設計工具中選取表單,然後在 [屬性] 視窗中按一下 [事件] 按鈕。

  11. 選取 FormClosing 事件,然後按 ENTER 產生事件處理常式。

  12. 以下列程式碼取代產生的方法。

    FormClosing 事件處理常式會呼叫 SaveSettings 方法,而在下一章節所加入的登出功能也會使用這個方法。 SaveSettings 方法會先確定使用者尚未登出。 它會檢查目前主體所傳回之 IIdentityAuthenticationType 屬性,以確定使用者尚未登出。 目前主體則是透過 static CurrentPrincipal 屬性所擷取。 如果使用者已經過驗證可使用用戶端應用程式服務,驗證類型將會是 "ClientForms"。 SaveSettings 方法不能只檢查 IIdentity.IsAuthenticated 屬性,因為使用者在登出後可能擁有有效的 Windows 識別。

    如果使用者尚未登出,SaveSettings 方法會呼叫在此程序稍早所產生之 Settings 類別的 Save 方法。 如果驗證 Cookie 已逾期,這個方法會擲回 WebException。 只有在應用程式組態中已選取 [要求使用者在伺服器 Cookie 過期時必須再次登入] 才會發生這種情況。 如需詳細資訊,請參閱 HOW TO:設定用戶端應用程式服務。 SaveSettings 方法會透過呼叫 ValidateUser 顯示登入對話方塊的方式,處理 Cookie 逾期。 如果使用者成功登入,SaveSettings 方法會呼叫本身以嘗試再次儲存設定。

    如同先前的程式碼,如果遠端服務無法使用,SaveSettings 方法就會顯示錯誤訊息。 如果設定提供者無法存取遠端服務,則設定仍然會儲存在本機快取中,然後在應用程式重新啟動時重新載入。

    Private Sub Form1_FormClosing(ByVal sender As Object, _
        ByVal e As FormClosingEventArgs) Handles Me.FormClosing
    
        SaveSettings()
    
    End Sub
    
    Private Sub SaveSettings()
    
        ' Return without saving if the authentication type is not
        ' "ClientForms". This indicates that the user is logged out.
        If Not Thread.CurrentPrincipal.Identity.AuthenticationType _
            .Equals("ClientForms") Then Return
    
        Try
    
            My.Settings.Save()
    
        Catch ex As WebException
    
            If ex.Message.Contains("You must log on to call this method.") Then
    
                MessageBox.Show( _
                    "Your login has expired. Please log in again to save " & _
                    "your settings.", "Attempting to save settings...")
    
                Dim isAuthorized As Boolean = False
    
                Try
    
                    ' Call ValidateUser with empty strings in order to 
                    ' display the login dialog box configured as a 
                    ' credentials provider.
                    If Not Membership.ValidateUser( _
                        String.Empty, String.Empty) Then
    
                        MessageBox.Show("Unable to authenticate. " & _
                            "Settings were not saved on the remote service.", _
                            "Not logged in", MessageBoxButtons.OK, _
                            MessageBoxIcon.Error)
    
                    Else
    
                        ' Try again.
                        SaveSettings()
    
                    End If
    
                Catch ex2 As System.Net.WebException
    
                    MessageBox.Show( _
                        "Unable to access the authentication service. " & _
                        "Settings were not saved on the remote service.", _
                        "Not logged in", MessageBoxButtons.OK, _
                        MessageBoxIcon.Warning)
    
                End Try
    
            Else
    
                MessageBox.Show("Unable to access the Web settings service. " & _
                    "Settings were not saved on the remote service.", _
                    "Not logged in", MessageBoxButtons.OK, _
                    MessageBoxIcon.Warning)
    
            End If
    
        End Try
    
    End Sub
    
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        SaveSettings();
    }
    
    private void SaveSettings()
    {
        // Return without saving if the authentication type is not
        // "ClientForms". This indicates that the user is logged out.
        if (!Thread.CurrentPrincipal.Identity.AuthenticationType
          .Equals("ClientForms")) return;
    
        try
        {
            Properties.Settings.Default.Save();
        }
        catch (WebException ex)
        {
            if (ex.Message.Contains("You must log on to call this method."))
            {
                MessageBox.Show(
                    "Your login has expired. Please log in again to save " +
                    "your settings.", "Attempting to save settings...");
    
                try
                {
                    // Call ValidateUser with empty strings in order to 
                    // display the login dialog box configured as a 
                    // credentials provider.
                    if (!Membership.ValidateUser(String.Empty, String.Empty))
                    {
                        MessageBox.Show("Unable to authenticate. " +
                            "Settings were not saved on the remote service.",
                            "Not logged in", MessageBoxButtons.OK, 
                            MessageBoxIcon.Error);
                    }
                    else
                    {
                        // Try again.
                        SaveSettings();
                    }
                }
                catch (System.Net.WebException)
                {
                    MessageBox.Show(
                        "Unable to access the authentication service. " +
                        "Settings were not saved on the remote service.",
                        "Not logged in", MessageBoxButtons.OK, 
                        MessageBoxIcon.Warning);
                }
            }
            else
            {
                MessageBox.Show("Unable to access the Web settings service. " +
                    "Settings were not saved on the remote service.", 
                    "Not logged in", MessageBoxButtons.OK, 
                    MessageBoxIcon.Warning);
            }
        }
    }
    
  13. 在 Form1 類別結尾處加入下列方法。

    如果有任何設定無法儲存,這段程式碼會處理 ClientSettingsProvider.SettingsSaved 事件並顯示警告。 如果設定服務無法使用或是驗證 Cookie 已經逾期,SettingsSaved 事件就不會發生。 SettingsSaved 事件發生時機的其中一個範例是如果使用者已經登出。 您可以在 Save 方法呼叫之前,將登出程式碼直接加入至 SaveSettings 方法以測試這個事件處理常式。 您可以使用的登出程式碼會在下一個章節中描述。

    Private WithEvents settingsProvider As ClientSettingsProvider = My.Settings _
        .Providers("System.Web.ClientServices.Providers.ClientSettingsProvider")
    
    Private Sub Form1_SettingsSaved(ByVal sender As Object, _
        ByVal e As SettingsSavedEventArgs) _
        Handles settingsProvider.SettingsSaved
    
        ' If any settings were not saved, display a list of them.
        If e.FailedSettingsList.Count > 0 Then
    
            Dim failedSettings As String = String.Join( _
                Environment.NewLine, e.FailedSettingsList.ToArray())
    
            Dim message As String = String.Format("{0}{1}{1}{2}", _
                "The following setting(s) were not saved:", _
                Environment.NewLine, failedSettings)
    
            MessageBox.Show(message, "Unable to save settings", _
                MessageBoxButtons.OK, MessageBoxIcon.Warning)
    
        End If
    
    End Sub
    
    private void Form1_SettingsSaved(object sender,
        SettingsSavedEventArgs e)
    {
        // If any settings were not saved, display a list of them.
        if (e.FailedSettingsList.Count > 0)
        {
            String failedSettings = String.Join(
                Environment.NewLine,
                e.FailedSettingsList.ToArray());
    
            String message = String.Format("{0}{1}{1}{2}",
                "The following setting(s) were not saved:",
                Environment.NewLine, failedSettings);
    
            MessageBox.Show(message, "Unable to save settings",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    
  14. 如果是使用 C#,請將下列程式碼加入至 Form1_Load 方法的結尾。 這個程式碼會讓在上一步驟中加入的方法與 SettingsSaved 事件產生關聯。

    ((ClientSettingsProvider)Properties.Settings.Default.Providers
        ["System.Web.ClientServices.Providers.ClientSettingsProvider"])
        .SettingsSaved += 
        new EventHandler<SettingsSavedEventArgs>(Form1_SettingsSaved);
    

若要在此時測試應用程式,請同時使用 employee 和 manager 身分執行數次,並在文字方塊中輸入不同的值。 這個值將會以每個使用者為基礎保存在所有工作階段中。

實作登出

當使用者在登入時選取 [儲存我的資訊] 核取方塊時,應用程式在後續執行時就會自動驗證使用者。 當應用程式在離線模式時,自動驗證仍然會繼續執行直到驗證 Cookie 逾期為止。 但是,有時候多個使用者會需要存取應用程式,或是單一使用者可能會偶爾使用不同的認證登入。 若要啟用這類案例,您必須實作登出功能,如同下列程序所述。

實作登出功能

  1. 在 Form1 設計工具中,從 [工具箱] 將 Button 控制項加入至表單。

  2. 在 [屬性] 視窗中,將 [(Name)] 的值指定為 logoutButton,並且將 [Text] 的值指定為 &Log Out。

  3. 按兩下 [logoutButton] 產生 Click 事件處理常式。

    程式碼編輯器隨即出現,並將游標置於 logoutButton_Click 方法中。

  4. 以下列程式碼取代產生的 logoutButton_Click 方法。

    這個事件處理常式會先呼叫在先前章節中加入的 SaveSettings 方法。 然後事件處理常式會呼叫 ClientFormsAuthenticationMembershipProvider.Logout 方法。 如果驗證服務無法使用,Logout 方法將擲回 WebException。 在上述情形中,logoutButton_Click 方法會顯示警告訊息,並且暫時切換至離線模式將使用者登出。 下一章節會描述離線模式。

    登出會刪除本機驗證 Cookie,因此當重新啟動應用程式時就需要登入。 在登出後,事件處理常式就會重新啟動應用程式。 應用程式重新啟動時,會在歡迎訊息後顯示登入對話方塊。 歡迎訊息可以清楚表示應用程式已重新啟動。 如果使用者必須登入才能儲存設定,然後因為應用程式重新啟動而必須再登入一次時,如此可以避免可能的混淆情況。

    Private Sub logoutButton_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles logoutButton.Click
    
        SaveSettings()
    
        Dim authProvider As ClientFormsAuthenticationMembershipProvider = _
            CType(System.Web.Security.Membership.Provider,  _
            ClientFormsAuthenticationMembershipProvider)
    
        Try
    
            authProvider.Logout()
    
        Catch ex As WebException
    
            MessageBox.Show("Unable to access the authentication service." & _
                Environment.NewLine & "Logging off locally only.", _
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            ConnectivityStatus.IsOffline = True
            authProvider.Logout()
            ConnectivityStatus.IsOffline = False
    
        End Try
    
        Application.Restart()
    
    End Sub
    
    private void logoutButton_Click(object sender, EventArgs e)
    {
        SaveSettings();
    
        ClientFormsAuthenticationMembershipProvider authProvider =
            (ClientFormsAuthenticationMembershipProvider)
            System.Web.Security.Membership.Provider;
    
        try
        {
            authProvider.Logout();
        }
        catch (WebException ex)
        {
            MessageBox.Show("Unable to access the authentication service." +
                Environment.NewLine + "Logging off locally only.",
                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            ConnectivityStatus.IsOffline = true;
            authProvider.Logout();
            ConnectivityStatus.IsOffline = false;
        }
    
        Application.Restart();
    }
    

若要測試登出功能,請執行應用程式然後在 [登入] 對話方塊上選取 [儲存我的資訊]。 然後關閉再重新啟動應用程式以確認不再需要登入。 最後,按一下 [登出] 重新啟動應用程式。

啟用離線模式

在下列程序中,會將核取方塊加入至表單,讓使用者能夠進入離線模式。 將 static ConnectivityStatus.IsOffline 屬性設定為 true,表示應用程式為離線模式。 離線狀態會儲存在 Application.UserAppDataPath 屬性所指定的本機硬碟位置中。 這表示離線狀態是以個別使用者以及應用程式為基礎儲存。

在離線模式中,所有的用戶端應用程式服務要求會從本機快取擷取資料,而不是嘗試存取服務。 在預設組態中,本機資料包含以加密格式儲存的使用者密碼。 這可以讓使用者在應用程式處於離線模式時仍能登入。 如需詳細資訊,請參閱 HOW TO:設定用戶端應用程式服務

在應用程式中啟用離線模式

  1. 在 [方案總管] 中的 ClientAppServicesDemo 專案中選取 Form1,然後選取 Visual Studio 主功能表中的 [檢視 | 設計工具]。

  2. 在設計工具中,將 CheckBox 控制項加入至表單。

  3. 在 [屬性] 視窗中,將 [(Name)] 的值指定為 workOfflineCheckBox,並且將 [Text] 的值指定為 &Work offline。

  4. 在 [屬性] 視窗中,按一下 [事件] 按鈕。

  5. 選取 CheckedChanged 事件,然後按 ENTER 產生事件處理常式。

  6. 以下列程式碼取代產生的方法。

    這段程式碼會更新 IsOffline 值,然後在返回線上模式時以無訊息模式重新驗證使用者。 ClientFormsIdentity.RevalidateUser 方法會使用已快取的認證,所以使用者不需要明確地進行登入動作。 如果驗證服務無法使用,就會出現警告訊息,而應用程式仍然保持離線狀態。

    注意事項注意事項

    RevalidateUser 方法只是為了方便而使用。 因為它沒有傳回值,因此無法表示重新驗證是否失敗。 例如,如果在伺服器上的使用者認證已變更,重新驗證就可能會失敗。 在這種情況中,您可能想要加入在服務呼叫失敗之後能夠明確驗證使用者的程式碼。 如需詳細資訊,請參閱此逐步解說中的「存取 Web 設定」章節。

    在重新驗證後,這段程式碼會呼叫先前加入的 SaveSettings 方法,將任何變更儲存在本機 Web 設定中。 然後呼叫專案 Settings 類別 (在 C# 中當做 Properties.Settings.Default 存取,而在 Visual Basic 中當做 My.Settings 存取) 的 Reload 方法,擷取伺服器上任何新增的值。

    Private Sub workOfflineCheckBox_CheckedChanged( _
        ByVal sender As Object, ByVal e As EventArgs) _
        Handles workOfflineCheckBox.CheckedChanged
    
        ConnectivityStatus.IsOffline = workOfflineCheckBox.Checked
    
        If Not ConnectivityStatus.IsOffline Then
    
            Try
    
                ' Silently re-validate the user.
                CType(System.Threading.Thread.CurrentPrincipal.Identity,  _
                    ClientFormsIdentity).RevalidateUser()
    
                ' If any settings have been changed locally, save the new
                ' new values to the Web settings service.
                SaveSettings()
    
                ' If any settings have not been changed locally, check 
                ' the Web settings service for updates. 
                My.Settings.Reload()
    
            Catch ex As WebException
    
                MessageBox.Show( _
                    "Unable to access the authentication service. " & _
                    Environment.NewLine + "Staying in offline mode.", _
                    "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
                workOfflineCheckBox.Checked = True
    
            End Try
    
        End If
    
    End Sub
    
    private void workOfflineCheckBox_CheckedChanged(
        object sender, EventArgs e)
    {
        ConnectivityStatus.IsOffline = workOfflineCheckBox.Checked;
        if (!ConnectivityStatus.IsOffline)
        {
            try
            {
                // Silently re-validate the user.
                ((ClientFormsIdentity)
                    System.Threading.Thread.CurrentPrincipal.Identity)
                    .RevalidateUser();
    
                // If any settings have been changed locally, save the new
                // new values to the Web settings service.
                SaveSettings();
    
                // If any settings have not been changed locally, check 
                // the Web settings service for updates. 
                Properties.Settings.Default.Reload();
            }
            catch (WebException)
            {
                MessageBox.Show(
                    "Unable to access the authentication service. " +
                    Environment.NewLine + "Staying in offline mode.",
                    "Warning", MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                workOfflineCheckBox.Checked = true;
            }
        }
    }
    
  7. 將下列程式碼加入至 Form1_Load 方法的結尾,以確定核取方塊會顯示目前的連接狀態。

    workOfflineCheckBox.Checked = ConnectivityStatus.IsOffline
    
    workOfflineCheckBox.Checked = ConnectivityStatus.IsOffline;
    

如此完成了範例應用程式。 若要測試離線功能,請執行應用程式、使用 employee 或 manager 的身分登入,然後選取 [離線工作]。 修改文字方塊中的值,然後關閉應用程式 再重新啟動。 在登入前,以滑鼠右鍵按一下工作列上告知區域中的 ASP.NET 程式開發伺服器圖示,然後按一下 [停止]。 然後以正常的方式登入。 即使伺服器並未在執行中,您仍然可以登入。 請修改文字方塊的值、結束然後重新啟動,以檢視修改過的值。

摘要

在這個逐步解說中,您已學習到如何在 Windows Form 應用程式中啟用與使用用戶端應用程式服務。 在設定測試伺服器後,您可以將程式碼加入至應用程式驗證使用者,並且從伺服器擷取使用者角色和應用程式設定。 您也學習了如何啟用離線模式,以便讓應用程式在無法連接時,使用本機資料快取而不是遠端服務。

後續步驟

現實的應用程式會從遠端伺服器存取許多使用者的資料,而遠端伺服器並非隨時都能使用,或是可能會在未告知的情況下關機。 若要讓應用程式更強固,就必須在服務無法使用時適當回應各種情況。 這個逐步解說包含 try/catch 區塊攔截 WebException,然後在服務無法使用時顯示錯誤訊息。 在實際執行的程式碼中,您可能想要藉由切換至離線模式、結束應用程式,或拒絕存取特定功能的方式處理這種情況。

若要增加應用程式的安全性,請確定在部署之前已徹底的測試應用程式與伺服器。

請參閱

工作

HOW TO:設定用戶端應用程式服務

逐步解說:使用 ASP.NET 應用程式服務

概念

用戶端應用程式服務概觀

其他資源

用戶端應用程式服務

ASP.NET 網站管理工具

建立及設定 SQL Server 的應用程式服務資料庫