チュートリアル : クライアント アプリケーション サービスの使用

このトピックでは、クライアント アプリケーション サービスを使用してユーザーを認証し、ユーザーのロールおよび設定を取得する Windows アプリケーションを作成する方法について説明します。

このチュートリアルでは次のタスクを行います。

  • Windows フォーム アプリケーションを作成し、Visual Studio プロジェクト デザイナーを使用してクライアント アプリケーション サービスを有効にし、構成します。

  • アプリケーション サービスをホストし、クライアント構成をテストするシンプルな ASP.NET Web サービス アプリケーションを作成します。

  • フォーム認証をアプリケーションに追加します。 最初に、ハードコーディングされたユーザー名とパスワードを使用してサービスをテストします。 次に、アプリケーション構成でログイン フォームを資格情報プロバイダーとして指定することにより、ログイン フォームを追加します。

  • "manager" ロールのユーザーのみがボタンを有効にしたり表示したりできる、ロールベースの機能を追加します。

  • Web 設定にアクセスします。 まず、プロジェクト デザイナーの [設定] ページで、認証済み (テスト) ユーザーの Web 設定を読み込みます。 次に、Windows フォーム デザイナーを使用して、テキスト ボックスを Web 設定にバインドします。 最後に、変更した値をサーバーに保存します。

  • ログアウトを実装します。 ログアウト オプションをフォームに追加し、ログアウト メソッドを呼び出します。

  • オフライン モードを有効にします。 ユーザーが接続状態を指定できるチェック ボックスを用意します。 この値を使用して、クライアント アプリケーション サービス プロバイダーが Web サービスにアクセスする代わりに、ローカル キャッシュ データを使用するかどうかを指定します。 最後に、アプリケーションがオンライン モードに戻ったときに、現在のユーザーを再認証します。

必須コンポーネント

このチュートリアルを完了するには、次のコンポーネントが必要です。

  • Visual Studio 2008.

クライアント アプリケーションの作成

最初に、Windows フォーム プロジェクトを作成します。 このチュートリアルでは、多くの開発者にとってなじみ深い Windows フォームを使用していますが、プロセスは Windows Presentation Foundation (WPF) プロジェクトと似ています。

クライアント アプリケーションを作成してクライアント アプリケーション サービスを有効にするには

  1. Visual Studio で、[ファイル]、[新規作成]、[プロジェクト] の順にクリックします。

  2. [新しいプロジェクト] ダイアログ ボックスの [プロジェクトの種類] ペインで、[Visual Basic] または [Visual C#] ノードを展開し、[Windows] を選択します。

  3. [.NET Framework 3.5] が選択されていることを確認し、[Windows フォーム アプリケーション] テンプレートを選択します。

  4. [プロジェクト名] を ClientAppServicesDemo に変更し、[OK] をクリックします。

    Visual Studio で新しい Windows フォーム プロジェクトが開きます。

  5. [プロジェクト] メニューの [ClientAppServicesDemo のプロパティ] をクリックします。

    プロジェクト デザイナーが表示されます。

  6. [サービス] タブで、[クライアント アプリケーション サービスを有効にする] をクリックします。

  7. [フォーム認証を使用する] が選択されていることを確認し、[認証サービスの場所][ロール サービスの場所]、および [Web 設定サービスの場所] を https://localhost:55555/AppServices に設定します。

  8. Visual Basic では、[アプリケーション] タブで、[認証モード][アプリケーション定義] に設定します。

指定した設定は、アプリケーションの app.config ファイルに格納されます。

この時点で、アプリケーションは、同じホストから 3 つすべてのサービスにアクセスするように構成されました。 次のセクションでは、ホストを単純な Web サービス アプリケーションとして作成し、クライアント構成をテストできるようにします。

アプリケーション サービス ホストの作成

ここでは、ローカル SQL Server Compact 3.5 データベース ファイルからユーザー データにアクセスする単純な Web サービス アプリケーションを作成します。 次に、ASP.NET Web サイト管理ツールを使用し、データベースにデータを設定します。 この単純な構成を使用すると、クライアント アプリケーションをすばやくテストできます。 また、完全な SQL Server データベースからユーザー データにアクセスしたり、カスタムの MembershipProvider クラスおよび RoleProvider クラスを介してユーザー データにアクセスしたりするよう Web サービス ホストを構成することもできます。 詳細については、「SQL Server 向けアプリケーション サービス データベースの作成と構成」を参照してください。

次の手順では、AppServices Web サービスを作成および構成する方法を示します。

アプリケーション サービス ホストを作成および構成するには

  1. ソリューション エクスプローラーで、ClientAppServicesDemo ソリューションを選択し、[ファイル] メニューの [追加]、[新しいプロジェクト] を順にクリックします。

  2. [新しいプロジェクトの追加] ダイアログ ボックスの [プロジェクトの種類] ペインで、[Visual Basic] または [Visual C#] ノードを展開し、[Web] を選択します。

  3. [.NET Framework 3.5] が選択されていることを確認し、[ASP.NET Web サービス アプリケーション] テンプレートを選択します。

  4. [プロジェクト名] を AppServices に変更し、[OK] をクリックします。

    新しい 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> タグの前に、次のマークアップを追加します。

    このマークアップの authenticationService 要素、profileService 要素、および roleService 要素が、アプリケーション サービスを有効にし、構成します。 テストのために、authenticationService 要素の requireSSL 属性を "false" に設定します。 profileService 要素の readAccessProperties 属性と writeAccessProperties 属性は、WebSettingsTestText プロパティが読み書き可能であることを示しています。

    注意

    実行コードでは、認証サービスには、常に SSL (Secure Sockets Layer) を使用して HTTPS プロトコルによってアクセスします。 SSL のセットアップ方法については、「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> 要素内部に置かれるように、次のマークアップを <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 Web サイト管理ツールを使用し、サービスの構成の完了およびローカル データベース ファイルへのデータの設定を行います。 employee および manager という名前の 2 つのロールに属している、同じ名前の 2 人のユーザーを追加します。 ユーザーのパスワードは、それぞれ employee! と manager! です。

メンバーシップおよびロールを構成するには

  1. ソリューション エクスプローラーで、AppServices プロジェクトを選択し、[プロジェクト] メニューの [ASP.NET 構成] をクリックします。

    ASP.NET Web サイト管理ツールが表示されます。

  2. [セキュリティ] タブの [手順に従ってセキュリティを構成するには、セキュリティ設定ウィザードを使用してください。] をクリックします。

    セキュリティ設定ウィザードが表示され、[ようこそ] が表示されます。

  3. [次へ] をクリックします。

    [アクセス方法の選択] が表示されます。

  4. [インターネットから] を選択します。 これにより、Windows 認証ではなくフォーム認証を使用するようにサービスが構成されます。

  5. [次へ] を 2 回クリックします。

    [ロールの定義] が表示されます。

  6. [この Web サイトにロールを有効化します。] を選択します。

  7. [次へ] をクリックします。 [新しいロールの作成] フォームが表示されます。

  8. [新しいロール名] ボックスに「manager」と入力し、[ロールの追加] をクリックします。

    [既存のロール] テーブルに、指定した値が表示されます。

  9. [新しいロール名] ボックスの「manager」を「employee」に置き換え、[ロールの追加] をクリックします。

    [既存のロール] テーブルに、新しい値が表示されます。

  10. [次へ] をクリックします。

    [新しいユーザーの追加] が表示されます。

  11. [ユーザーの作成] フォームで、次の値を指定します。

    [ユーザー名]

    manager

    [パスワード]

    manager!

    [パスワードの確認入力]

    manager!

    [電子メール]

    manager@contoso.com

    [セキュリティの質問]

    manager

    [セキュリティ返答]

    manager

  12. [ユーザーの作成] をクリックします。

    成功メッセージが表示されます。

    注意

    [電子メール][セキュリティの質問]、および [セキュリティ返答] の各値がフォームで必要とされますが、この例では使用しません。

  13. [続行] をクリックします。

    [ユーザーの作成] フォームが表示されます。

  14. [ユーザーの作成] フォームで、次の値を指定します。

    [ユーザー名]

    employee

    [パスワード]

    employee!

    [パスワードの確認入力]

    employee!

    [電子メール]

    employee@contoso.com

    [セキュリティの質問]

    Employee

    [セキュリティ返答]

    employee

  15. [ユーザーの作成] をクリックします。

    成功メッセージが表示されます。

  16. [完了] をクリックします。

    Web サイト管理ツールが再表示されます。

  17. [ユーザーの管理] をクリックします。

    ユーザーの一覧が表示されます。

  18. employee ユーザーの [ロールの編集] をクリックし、employee ロールを選択します。

  19. manager ユーザーの [ロールの編集] をクリックし、manager ロールを選択します。

  20. Web サイト管理ツールをホストするブラウザー ウィンドウを閉じます。

  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 Version 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 パラメーターを変更します。 たとえば、2 つ目の "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 メソッドは警告メッセージを表示し、オフライン モードで起動するかどうかをユーザーに確認します。 この機能には、[オフラインでログインできるようにパスワードのハッシュをローカルに保存する] 機能が必要です。詳細については、「方法 : クライアント アプリケーション サービスを構成する」を参照してください。 この機能は、新しいプロジェクトについては既定で有効になっています。

    ユーザーが検証されなかった場合、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 インターフェイスを実装するクラスです。 このインターフェイスには、ClientFormsAuthenticationCredentials オブジェクトを返す GetCredentials というメソッドが 1 つ含まれています。 次の手順では、自身を表示し、ユーザー指定の資格情報を返す GetCredentials を実装したログイン ダイアログ ボックスを作成する方法について説明します。

Visual Basic にはログイン フォーム テンプレートがあるため、Visual Basic と C# とでは手順が異なります。 テンプレートを使用すると、時間の節約になり、コーディング作業が容易になります。

ログイン ダイアログ ボックスを資格情報プロバイダーとして作成するには (Visual Basic の場合)

  1. ソリューション エクスプローラーで、ClientAppServicesDemo プロジェクトを選択し、[プロジェクト] メニューの [新しい項目の追加] をクリックします。

  2. [新しい項目の追加] ダイアログ ボックスで、[ログイン フォーム] テンプレートを選択し、[ファイル名] を Login.vb に変更し、[追加] をクリックします。

    Windows フォーム デザイナーで、ログイン ダイアログ ボックスが開きます。

  3. デザイナーで、[OK] ボタンをクリックし、次に [プロパティ] ウィンドウで、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 です。

注意

この時点では [Remember me] チェック ボックスはオンにしません。これをオンにすると、このチュートリアルの後半でログアウトを実装するまで別のユーザーでログインできなくなります。

ロール ベースの機能の追加

次の手順では、manager ロールのユーザーに対してのみ表示されるボタンをフォームに追加します。

ユーザー ロールに応じてユーザー インターフェイスを変更するには

  1. ソリューション エクスプローラーの ClientAppServicesDemo プロジェクトで Form1 を選択し、Visual Studio のメイン メニューで [表示]、[デザイナー] の順にクリックします。

  2. デザイナーで、[ツールボックス] から Button コントロールをフォームに追加します。

  3. [プロパティ] ウィンドウで、ボタンに対して次のプロパティを設定します。

    プロパティ

    (Name)

    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 の期限が切れた場合は常に再度ログオンすることをユーザーに要求する] をオンにしている場合にのみ必要です。 詳細については、「方法 : クライアント アプリケーション サービスを構成する」を参照してください。

    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 プロパティにバインドします。 また、Web 設定サービスが使用できないことを示す WebException がスローされた場合、このメソッドはエラー メッセージを表示します。

    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 ID を持っている可能性があるためです。

    ユーザーがログアウトしていない場合は、SaveSettings メソッドは、この手順で前に生成した Settings クラスの Save メソッドを呼び出します。 このメソッドは、認証 Cookie の期限が切れている場合は WebException をスローできます。 これは、アプリケーション構成で [サーバー Cookie の期限が切れた場合は常に再度ログオンすることをユーザーに要求する] をオンにしている場合にのみ発生します。 詳細については、「方法 : クライアント アプリケーション サービスを構成する」を参照してください。 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 イベントが発生する 1 つの例として、ユーザーが既にログアウトしていた場合が挙げられます。 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 クラスの最後に次のコードを追加します。 このコードは、1 つ前の手順で追加したメソッドと SettingsSaved イベントを関連付けます。

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

この時点でアプリケーションをテストするには、employee と manager の両方のユーザーとして複数回アプリケーションを実行し、テキスト ボックスに異なる値を入力します。 この値は、ユーザー単位で、セッション間で保持されます。

ログアウトの実装

ログイン時にユーザーが [Remember me] チェック ボックスをオンにしている場合は、アプリケーションは以降の実行時、ユーザーを自動的に認証するようになります。 自動認証は、認証 Cookie の期限が切れるまで、アプリケーションがオフライン モードの間も続きます。 ただし、場合によっては、複数のユーザーが 1 つのアプリケーションにアクセスしたり、1 人のユーザーが異なる資格情報でログインすることがあります。 このシナリオに対応するためには、次の手順で説明するログアウト機能を実装する必要があります。

ログアウト機能を実装するには

  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();
    }
    

ログアウト機能をテストするには、アプリケーションを実行し、ログイン ダイアログ ボックスの [Remember me] をオンにします。 次に、アプリケーションを閉じて再起動することにより、ログインが必要ないことを確認します。 最後に、[Log out] をクリックしてアプリケーションを再起動します。

オフライン モードの有効化

次の手順で、オフライン モードにするためのチェック ボックスをフォームに追加します。 static ConnectivityStatus.IsOffline プロパティを true に設定することにより、アプリケーションはオフライン モードを示します。 オフライン ステータスは、Application.UserAppDataPath プロパティによって示されている場所のローカル ハード ディスクに格納されます。 つまり、オフライン ステータスは、ユーザーおよびアプリケーション単位で格納されます。

オフライン モードでは、すべてのクライアント アプリケーション サービスは、サービスにアクセスするのではなく、ローカル キャッシュからデータを取得します。 既定の構成では、ローカル データには、ユーザーの暗号化されたパスワードが含まれます。 これにより、アプリケーションがオフライン モードである間でも、ユーザーのログインが可能になります。 詳細については、「方法 : クライアント アプリケーション サービスを構成する」を参照してください。

アプリケーションでオフライン モードを有効にするには

  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 でログインし、[Work offline] をクリックします。 テキスト ボックス内の値を変更したら、アプリケーションを閉じます。 アプリケーションを再起動します。 ログインする前に、タスク バーの通知領域にある ASP.NET 開発サーバー アイコンを右クリックし、[停止] をクリックします。 次に、通常どおりログインします。 サーバーが実行されていない場合でも、ログインできます。 テキスト ボックスの値を変更したら、変更した値を確認するために終了し、再起動します。

概要

このチュートリアルでは、Windows フォーム アプリケーションでクライアント アプリケーション サービスを有効にして使用する方法について学習しました。 テスト サーバーをセットアップした後で、ユーザーを認証し、ユーザー ロールとアプリケーション設定をサーバーから取得するコードをアプリケーションに追加しました。 また、アプリケーションが接続を使用できない場合に、リモート サービスではなくローカル データ キャッシュを使用するように、オフライン モードを有効にする方法についても学習しました。

次の手順

実際のアプリケーションでは、常に使用可能ではなかったり、突然停止する可能性もあるリモート サーバーから、多くのユーザーのデータを取得することになります。 アプリケーションの堅牢性を向上させるためには、サービスが利用できない場合に適切に対応できることが必要です。 このチュートリアルでは、try/catch ブロックを使用して WebException をキャッチして、サービスが使用できない場合にエラー メッセージが表示されるようにしています。 実行コードでは、オフラインへの切り替え、アプリケーションの終了、または特定機能へのアクセスの拒否を行うことにより、サービスが使用できない場合に対処することが必要になります。

アプリケーションのセキュリティを向上させるために、配置前に、アプリケーションとサーバーに対して十分にテストを行ってください。

参照

処理手順

方法 : クライアント アプリケーション サービスを構成する

チュートリアル : ASP.NET アプリケーション サービスの使用

概念

クライアント アプリケーション サービスの概要

その他の技術情報

クライアント アプリケーション サービス

ASP.NET Web サイト管理ツール

SQL Server 向けアプリケーション サービス データベースの作成と構成