ユーザーにロールを割り当てる (VB)

作成者: Scott Mitchell

注意

この記事が作成されて以来、ASP.NET メンバーシップ プロバイダーは ASP.NET Identity に置き換えられました。 この記事の執筆時点で取り上げられたメンバーシップ プロバイダーではなく 、ASP.NET ID プラットフォームを使用するようにアプリを更新することを強くお勧めします。 ASP.NET ID には、ASP.NET メンバーシップ システムに比して、次のような多くの利点があります。

  • パフォーマンスの向上
  • 拡張性とテスト性の向上
  • OAuth、OpenID Connect、および 2 要素認証のサポート
  • クレームベースの ID のサポート
  • ASP.Net Core との相互運用性の向上

コードのダウンロード または PDF のダウンロード

このチュートリアルでは、2 つの ASP.NET ページを作成して、ユーザーがどのロールに属するかの管理を支援します。 最初のページには、特定のロールに属しているユーザー、特定のユーザーが属しているロール、特定のロールに対して特定のユーザーを割り当てたり削除したりする機能が含まれます。 2 番目のページでは、CreateUserWizard コントロールを拡張して、新しく作成されたユーザーが属するロールを指定する手順を含めます。 これは、管理者が新しいユーザー アカウントを作成できるシナリオで役立ちます。

はじめに

前の チュートリアル では、Roles フレームワークと SqlRoleProviderを調べました。クラスを使用してロールを Roles 作成、取得、削除する方法を確認しました。 ロールの作成と削除に加えて、ロールに対するユーザーの割り当てまたは削除が可能である必要があります。 残念ながら、ASP.NET には、ユーザーがどのロールに属しているのかを管理するための Web コントロールは付属していません。 代わりに、これらの関連付けを管理するために独自の ASP.NET ページを作成する必要があります。 良いニュースは、ロールへのユーザーの追加と削除は非常に簡単です。 Rolesクラスには、1 つ以上のユーザーを 1 つ以上のロールに追加するためのメソッドが多数含まれています。

このチュートリアルでは、2 つの ASP.NET ページを作成して、ユーザーがどのロールに属するかの管理を支援します。 最初のページには、特定のロールに属しているユーザー、特定のユーザーが属しているロール、特定のロールに対して特定のユーザーを割り当てたり削除したりする機能が含まれます。 2 番目のページでは、CreateUserWizard コントロールを拡張して、新しく作成されたユーザーが属するロールを指定する手順を含めます。 これは、管理者が新しいユーザー アカウントを作成できるシナリオで役立ちます。

それでは作業を始めましょう。

どのユーザーがどのロールに属しているのかを一覧表示する

このチュートリアルのビジネスの最初の順序は、ユーザーをロールに割り当てることができる Web ページを作成することです。 ユーザーをロールに割り当てる方法に関心を持つ前に、まず、どのユーザーがどのロールに属しているかを判断する方法に集中しましょう。 この情報を表示するには、"ロール別" と "ユーザー別" の 2 つの方法があります。訪問者がロールを選択し、そのロールに属しているすべてのユーザーを表示することも ("by role" 表示)、訪問者にユーザーの選択を求め、そのユーザーに割り当てられたロール ("ユーザー別" 表示) を表示することもできます。

"ロール別" ビューは、訪問者が特定のロールに属するユーザーのセットを知りたい場合に役立ちます。"ユーザー別" ビューは、訪問者が特定のユーザーのロールを知る必要がある場合に最適です。 ページに "ロール別" インターフェイスと "ユーザー別" インターフェイスの両方を含めてみましょう。

まず、"by user" インターフェイスを作成します。 このインターフェイスは、ドロップダウン リストとチェック ボックスの一覧で構成されます。 ドロップダウン リストには、システム内のユーザーのセットが設定されます。チェックボックスはロールを列挙します。 ドロップダウン リストからユーザーを選択すると、ユーザーが属しているロールがチェックされます。 ページにアクセスするユーザーは、チェックボックスをチェックまたはオフにして、選択したユーザーを対応するロールに追加または削除できます。

注意

ドロップダウン リストを使用してユーザー アカウントを一覧表示することは、何百ものユーザー アカウントがある可能性がある Web サイトには理想的な選択肢ではありません。 ドロップダウン リストは、ユーザーが比較的短いオプションの一覧から 1 つの項目を選択できるように設計されています。 リスト アイテムの数が増えるにつれて、すぐに扱いにくくなります。 多数のユーザー アカウントを持つ可能性がある Web サイトを構築する場合は、ページ可能な GridView やフィルター可能なインターフェイスなどの代替ユーザー インターフェイスを使用することを検討してください。このインターフェイスを使用すると、訪問者はレターを選択するように求め、ユーザー名が選択した文字で始まるユーザーのみが表示されます。

手順 1: "ユーザー別" ユーザー インターフェイスの構築

ページを UsersAndRoles.aspx 開きます。 ページの上部に、 という名前 ActionStatus のラベル Web コントロールを追加し、そのプロパティを Text クリアします。 このラベルを使用して、実行されたアクションに関するフィードバックを提供し、"User Tito has added to the Administrators role"、"User Jisun has removed from the Supervisors role" (ユーザー Tito が管理者ロールに追加されました)、"ユーザー Jisun が Supervisors ロールから削除されました" などのメッセージを表示します。これらのメッセージを目立たせるために、Label の CssClass プロパティを "Important" に設定します。

<p align="center"> 
     <asp:Label ID="ActionStatus" runat="server" CssClass="Important"> </asp:Label> 
</p>

次に、次の CSS クラス定義をスタイルシートに Styles.css 追加します。

.Important 
{ 
     font-size: large; 
     color: Red; 
}

この CSS 定義は、大きな赤いフォントを使用してラベルを表示するようにブラウザーに指示します。 図 1 は、Visual Studio Designerによるこの効果を示しています。

Label の CssClass プロパティは、大きく赤いフォントになります

図 1: ラベルのプロパティの CssClass 結果が大きく、赤いフォントになります (フルサイズの画像を表示するにはクリックします)

次に、ページに DropDownList を追加し、そのプロパティを IDUserList設定し、そのプロパティを AutoPostBack True に設定します。 この DropDownList を使用して、システム内のすべてのユーザーを一覧表示します。 この DropDownList は、MembershipUser オブジェクトのコレクションにバインドされます。 DropDownList で MembershipUser オブジェクトの UserName プロパティを表示する (リスト アイテムの値として使用する) ため、DropDownList の DataTextField プロパティと DataValueField プロパティを "UserName" に設定します。

DropDownList の下に、 という名前 UsersRoleListの Repeater を追加します。 この Repeater では、システム内のすべてのロールが一連のチェック ボックスとして一覧表示されます。 次の宣言型マークアップを使用して、Repeater ItemTemplate の を定義します。

<asp:Repeater ID="UsersRoleList" runat="server"> 
     <ItemTemplate> 
          <asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true" 
               Text='<%# Container.DataItem %>' /> 
          <br /> 
     </ItemTemplate> 
</asp:Repeater>

マークアップには ItemTemplate 、 という名前の 1 つの CheckBox Web コントロールが RoleCheckBox含まれています。 CheckBox の AutoPostBack プロパティは True に設定され、 Text プロパティは に Container.DataItemバインドされます。 データバインド構文が単純である Container.DataItem 理由は、Roles フレームワークがロール名の一覧を文字列配列として返し、この文字列配列が Repeater にバインドされるためです。 この構文を使用してデータ Web コントロールにバインドされた配列の内容を表示する理由の詳細については、このチュートリアルでは説明していません。 この問題の詳細については、「 Data Web コントロールへのスカラー配列のバインド」を参照してください。

この時点で、"by user" インターフェイスの宣言型マークアップは次のようになります。

<h3>Manage Roles By User</h3> 
<p> 
     <b>Select a User:</b> 
     <asp:DropDownList ID="UserList" runat="server" AutoPostBack="True" 
          DataTextField="UserName" DataValueField="UserName"> 
     </asp:DropDownList> 
</p> 
<p> 
     <asp:Repeater ID="UsersRoleList" runat="server"> 
          <ItemTemplate> 
               <asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true" 
                    Text='<%# Container.DataItem %>' /> 
               <br /> 
          </ItemTemplate> 
     </asp:Repeater> 
</p>

これで、ユーザー アカウントのセットを DropDownList にバインドし、ロールのセットを Repeater にバインドするコードを記述する準備ができました。 ページの分離コード クラスで、次のコードを使用して、 という名前 BindUsersToUserList の メソッドと という名前 BindRolesListの別のメソッドを追加します。

Private Sub BindUsersToUserList() 
     ' Get all of the user accounts 
     Dim users As MembershipUserCollection = Membership.GetAllUsers() 
     UserList.DataSource = users 
     UserList.DataBind() 
End Sub 
 
Private Sub BindRolesToList() 
     ' Get all of the roles 
     Dim roleNames() As String = Roles.GetAllRoles() 
     UsersRoleList.DataSource = roleNames 
     UsersRoleList.DataBind() 
End Sub

メソッドはBindUsersToUserList、 メソッドを使用してシステム内のすべてのユーザー アカウントをMembership.GetAllUsers取得します。 これにより、インスタンスのMembershipUserCollectionコレクションMembershipUserである オブジェクトが返されます。 その後、このコレクションは DropDownList に UserList バインドされます。 コレクションを構成するインスタンスにはMembershipUser、、EmailCreationDateIsOnline、、 などUserName、さまざまなプロパティが含まれています。 プロパティの値UserNameを表示するように DropDownList に指示するには、DropDownList DataTextField の プロパティとDataValueFieldプロパティが "UserName" に設定されていることを確認UserListします。

注意

Membership.GetAllUsersメソッドには 2 つのオーバーロードがあります。1 つは入力パラメーターを受け入れず、すべてのユーザーを返し、もう 1 つはページ インデックスとページ サイズの整数値を受け取り、指定されたユーザーのサブセットのみを返します。 ページング可能なユーザー インターフェイス要素に大量のユーザー アカウントが表示されている場合、2 番目のオーバーロードを使用すると、すべてのユーザー アカウントではなく、ユーザー アカウントの正確なサブセットのみが返されるため、より効率的にユーザーをページングできます。

メソッドは BindRolesToList 、システム内のロールを Roles 含む文字列配列を返すクラスの GetAllRoles メソッドを呼び出すことから始まります。 この文字列配列は、Repeater にバインドされます。

最後に、ページが最初に読み込まれるときに、これら 2 つのメソッドを呼び出す必要があります。 Page_Load イベント ハンドラーに次のコードを追加します。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Bind the users and roles 
          BindUsersToUserList() 
          BindRolesToList() 
     End If 
End Sub

このコードを配置した状態で、ブラウザーからページにアクセスしてください。画面は図 2 のようになります。 すべてのユーザー アカウントがドロップダウン リストに入力され、その下に各ロールがチェックボックスとして表示されます。 DropDownList と CheckBoxes のプロパティを True に設定 AutoPostBack しているため、選択したユーザーを変更するか、ロールをオンまたはオフにするとポストバックが発生します。 ただし、これらのアクションを処理するコードをまだ記述していないため、アクションは実行されません。 これらのタスクは、次の 2 つのセクションで取り組みます。

このページには、ユーザーとロールが表示されます

図 2: ページにユーザーとロールが表示されます (フルサイズの画像を表示する場合はクリックします)

選択したユーザーが属しているロールの確認

ページが最初に読み込まれるとき、または訪問者がドロップダウン リストから新しいユーザーを選択するたびに、選択したユーザーがそのロールに属している場合にのみ特定のロールのチェック ボックスがオンになるように、 のチェック ボックスを更新 UsersRoleListする必要があります。 これを実現するには、次のコードを使用して という名前 CheckRolesForSelectedUser のメソッドを作成します。

Private Sub CheckRolesForSelectedUser() 
     ' Determine what roles the selected user belongs to 
     Dim selectedUserName As String = UserList.SelectedValue 
     Dim selectedUsersRoles() As String = Roles.GetRolesForUser(selectedUserName) 
 
     ' Loop through the Repeater's Items and check or uncheck the checkbox as needed 
     For Each ri As RepeaterItem In UsersRoleList.Items 
          ' Programmatically reference the CheckBox 
          Dim RoleCheckBox As CheckBox = CType(ri.FindControl("RoleCheckBox"), CheckBox) 
          ' See if RoleCheckBox.Text is in selectedUsersRoles 
          If Linq.Enumerable.Contains(Of String)(selectedUsersRoles, RoleCheckBox.Text) Then 
               RoleCheckBox.Checked = True 
          Else 
               RoleCheckBox.Checked = False 
          End If 
     Next 
End Sub

上記のコードは、選択したユーザーが誰であるかを判断することから始まります。 次に、Roles クラスの GetRolesForUser(userName) メソッド を使用して、指定したユーザーのロールのセットを文字列配列として返します。 次に、Repeater の項目が列挙され、各アイテムの RoleCheckBox CheckBox がプログラムによって参照されます。 CheckBox は、対応するロールが文字列配列内 selectedUsersRoles に含まれている場合にのみチェックされます。

注意

バージョン 2.0 ASP.NET 使用している場合、構文は Linq.Enumerable.Contains(Of String)(...) コンパイルされません。 メソッドは Contains(Of String)LINQ ライブラリの一部であり、ASP.NET 3.5 の新機能です。 まだバージョン 2.0 ASP.NET 使用している場合は、代わりに メソッドをArray.IndexOf(Of String)使用します。

メソッドは CheckRolesForSelectedUser 、ページが最初に読み込まれるときと、DropDownList の選択したインデックスが変更されるたびに UserList 呼び出される 2 つの場合に呼び出す必要があります。 そのため、イベント ハンドラーからこのメソッドを Page_Load 呼び出します (および の BindUsersToUserList 呼び出し BindRolesToListの後)。 また、DropDownList SelectedIndexChanged のイベントのイベント ハンドラーを作成し、そこからこのメソッドを呼び出します。

Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Bind the users and roles 
          BindUsersToUserList() 
          BindRolesToList() 
          ' Check the selected user's roles 
          CheckRolesForSelectedUser() 
     End If 
End Sub 
 
... 
 
Protected Sub UserList_SelectedIndexChanged(ByVal sender As Object,ByVal e As System.EventArgs) Handles UserList.SelectedIndexChanged 
     CheckRolesForSelectedUser() 
End Sub

このコードを配置すると、ブラウザーを使用してページをテストできます。 ただし、ページには UsersAndRoles.aspx 現在、ロールにユーザーを割り当てる機能がないため、ロールを持つユーザーはいません。 ユーザーをロールに割り当てるためのインターフェイスをすぐに作成します。そのため、このコードが機能することを自分の言葉で確認して後で確認するか、テーブルにレコード aspnet_UsersInRoles を挿入してユーザーをロールに手動で追加して、この機能を今すぐテストすることができます。

ロールへのユーザーの割り当てと削除

訪問者が Repeater の UsersRoleList CheckBox をチェックまたはオフにした場合は、選択したユーザーを対応するロールに追加または削除する必要があります。 CheckBox の AutoPostBack プロパティは現在 True に設定されており、Repeater の CheckBox がオンまたはオフになっている場合は、ポストバックが発生します。 つまり、CheckBox CheckChanged のイベントのイベント ハンドラーを作成する必要があります。 CheckBox は Repeater コントロールに含まれているので、イベント ハンドラーのプラミングを手動で追加する必要があります。 まず、次のように、イベント ハンドラーをメソッドとして分離コード クラスに Protected 追加します。

Protected Sub RoleCheckBox_CheckChanged(ByVal sender As Object, ByVal e As EventArgs) 
 
End Sub

に戻り、このイベント ハンドラーのコードをすぐに記述します。 しかし、まず、イベント処理の配管を完了しましょう。 Repeater ItemTemplateの 内の CheckBox から、 を追加します OnCheckedChanged="RoleCheckBox_CheckChanged"。 この構文は、イベント ハンドラーを RoleCheckBox_CheckChanged の イベントにCheckedChangedRoleCheckBox結び付けます。

<asp:CheckBox runat="server" ID="RoleCheckBox" 
     AutoPostBack="true" 
     Text='<%# Container.DataItem %>' 
     OnCheckedChanged="RoleCheckBox_CheckChanged" />

最後のタスクは、イベント ハンドラーを RoleCheckBox_CheckChanged 完了することです。 まず、イベントを発生させた CheckBox コントロールを参照する必要があります。これは、この CheckBox インスタンスによって、その Text プロパティと Checked プロパティを介してチェックまたはオフにされたロールが示されるためです。 この情報を選択したユーザーの UserName と共に使用して、クラスAddUserToRoleまたは メソッドを使用してロールに対してユーザーをRoles追加またはRemoveUserFromRole削除します。

Protected Sub RoleCheckBox_CheckChanged(ByVal sender As Object, ByVal e As EventArgs) 
     'Reference the CheckBox that raised this event 
     Dim RoleCheckBox As CheckBox = CType(sender, CheckBox) 
 
     ' Get the currently selected user and role 
     Dim selectedUserName As String = UserList.SelectedValue 
     Dim roleName As String = RoleCheckBox.Text 
 
     ' Determine if we need to add or remove the user from this role 
     If RoleCheckBox.Checked Then 
          ' Add the user to the role 
          Roles.AddUserToRole(selectedUserName, roleName) 
          ' Display a status message 
          ActionStatus.Text = String.Format("User {0} was added to role {1}.", selectedUserName,roleName) 
     Else 
          ' Remove the user from the role 
          Roles.RemoveUserFromRole(selectedUserName, roleName) 
          ' Display a status message 
          ActionStatus.Text = String.Format("User {0} was removed from role {1}.", selectedUserName,roleName) 
     End If 
End Sub

上記のコードは、入力パラメーターを介して sender 使用できるイベントを発生させた CheckBox をプログラムで参照することから始まります。 CheckBox をオンにすると、選択したユーザーが指定したロールに追加され、それ以外の場合はロールから削除されます。 どちらの場合も、Label には ActionStatus 、実行したアクションを要約したメッセージが表示されます。

ブラウザーを使用してこのページをテストしてください。 ユーザー Tito を選択し、管理者と監督者の両方のロールに Tito を追加します。

管理者と監督者の役割に Tito が追加されました

図 3: Tito が管理者と監督者の役割に追加されました (フルサイズの画像を表示する をクリックします)

次に、ドロップダウン リストからユーザー Bruce を選択します。 ポストバックがあり、Repeater の CheckBox が を CheckRolesForSelectedUser介して更新されます。 Bruce はまだロールに属していないため、2 つのチェック ボックスはオフになっています。 次に、Bruce を Supervisors ロールに追加します。

Bruce がスーパーバイザー ロールに追加されました

図 4: Bruce がスーパーバイザー ロールに追加されました (クリックするとフルサイズの画像が表示されます)

メソッドの CheckRolesForSelectedUser 機能をさらに確認するには、Tito または Bruce 以外のユーザーを選択します。 チェック ボックスが自動的にオフになっていることに注意してください。これは、どのロールにも属しないことを示しています。 Tito に戻ります。 [管理者] と [スーパーバイザー] の両方のチェックボックスをオンにする必要があります。

手順 2: "ロール別" ユーザー インターフェイスの構築

この時点で、"ユーザー別" インターフェイスを完了し、"ロール別" インターフェイスに取り組み始める準備が整いました。 "ロール別" インターフェイスは、ドロップダウン リストからロールを選択するようにユーザーに求め、そのロールに属するユーザーのセットを GridView に表示します。

別の DropDownList コントロールを に追加します UsersAndRoles.aspx page。 この 1 つを Repeater コントロールの下に配置し、 という名前を付け RoleList、そのプロパティを AutoPostBack True に設定します。 その下に GridView を追加し、 という名前を付けます RolesUserList。 この GridView には、選択したロールに属しているユーザーが一覧表示されます。 GridView AutoGenerateColumns のプロパティを False に設定し、グリッドの Columns コレクションに TemplateField を追加し、そのプロパティを HeaderText "Users" に設定します。 という名前UserNameLabelItemTemplate Label プロパティに databinding 式Container.DataItemTextの値を表示するように TemplateField を定義します。

GridView を追加して構成すると、"ロール別" インターフェイスの宣言型マークアップは次のようになります。

<h3>Manage Users By Role</h3> 
<p> 
     <b>Select a Role:</b> 
     <asp:DropDownList ID="RoleList" runat="server" AutoPostBack="true"></asp:DropDownList> 
</p> 
<p> 
     <asp:GridView ID="RolesUserList" runat="server" AutoGenerateColumns="false" 
          EmptyDataText="No users belong to this role."> 
          <Columns> 
               <asp:TemplateField HeaderText="Users"> 
                    <ItemTemplate> 
                         <asp:Label runat="server" id="UserNameLabel" 
                              Text='<%# Container.DataItem %>'></asp:Label> 
                    </ItemTemplate> 
               </asp:TemplateField> 
          </Columns> 
     </asp:GridView> 
</p>

DropDownList に RoleList システム内の一連のロールを設定する必要があります。 これを行うには、 メソッドをBindRolesToList更新して、 メソッドRolesListによって返された文字列配列を Roles.GetAllRoles DropDownList (および Repeater) にUsersRoleListバインドします。

Private Sub BindRolesToList() 
     ' Get all of the roles 
     Dim roleNames() As String = Roles.GetAllRoles() 
     UsersRoleList.DataSource = roleNames 
     UsersRoleList.DataBind() 
 
     RoleList.DataSource = roleNames 
     RoleList.DataBind() 
End Sub

メソッドの最後の BindRolesToList 2 行が追加され、一連のロールが DropDownList コントロールに RoleList バインドされました。 図 5 は、ブラウザーを使用して表示した場合の最終結果を示しています。ドロップダウン リストには、システムの役割が設定されています。

ロールが RoleList DropDownList に表示される

図 5: ロールは DropDownList に RoleList 表示されます (クリックするとフルサイズの画像が表示されます)

選択したロールに属するユーザーの表示

ページが最初に読み込まれるか、DropDownList から RoleList 新しいロールが選択されたときに、そのロールに属するユーザーの一覧を GridView に表示する必要があります。 次のコードを使用して、 という名前 DisplayUsersBelongingToRole のメソッドを作成します。

Private Sub DisplayUsersBelongingToRole() 
     ' Get the selected role 
     Dim selectedRoleName As String = RoleList.SelectedValue 
 
     ' Get the list of usernames that belong to the role 
     Dim usersBelongingToRole() As String = Roles.GetUsersInRole(selectedRoleName) 
 
     ' Bind the list of users to the GridView 
     RolesUserList.DataSource = usersBelongingToRole 
     RolesUserList.DataBind() 
End Sub

このメソッドは、まず DropDownList から選択したロールを RoleList 取得します。 次に、 メソッドをRoles.GetUsersInRole(roleName)使用して、そのロールに属するユーザーの UserNames の文字列配列を取得します。 その後、この配列は GridView に RolesUserList バインドされます。

このメソッドは、ページが最初に読み込まれるときと、DropDownList で選択したロールが変更されたときの 2 つの状況で呼び出す RoleList 必要があります。 そのため、 の呼び出し後に Page_Load このメソッドが呼び出されるように、イベント ハンドラーを更新します CheckRolesForSelectedUser。 次に、 の イベントのSelectedIndexChangedイベント ハンドラーをRoleList作成し、そこからこのメソッドも呼び出します。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Bind the users and roles 
          BindUsersToUserList() 
          BindRolesToList() 
 
          ' Check the selected user's roles 
          CheckRolesForSelectedUser() 
 
          'Display those users belonging to the currently selected role 
          DisplayUsersBelongingToRole() 
     End If 
End Sub 
 
... 
 
Protected Sub RoleList_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RoleList.SelectedIndexChanged 
     DisplayUsersBelongingToRole() 
End Sub

このコードを配置すると、GridView には、 RolesUserList 選択したロールに属しているユーザーが表示されます。 図 6 に示すように、Supervisors ロールは、Bruce と Tito の 2 つのメンバーで構成されています。

GridView には、選択したロールに属しているユーザーの一覧が表示されます

図 6: GridView には、選択したロールに属しているユーザーの一覧が表示されます (クリックするとフルサイズの画像が表示されます)

選択したロールからのユーザーの削除

"削除" ボタンの RolesUserList 列が含まれるように GridView を拡張してみましょう。 特定のユーザーの [削除] ボタンをクリックすると、そのロールから削除されます。

まず、GridView に [削除] ボタン フィールドを追加します。 このフィールドを最も左のファイルとして表示し、そのプロパティを DeleteText "削除" (既定値) から "削除" に変更します。

[フィールド] ウィンドウに [削除] ボタンを追加する方法を示すスクリーンショット。

図 7: GridView に [削除] ボタンを追加します (クリックするとフルサイズの画像が表示されます)

[削除] ボタンをクリックするとポストバックが続き、GridView の RowDeleting イベントが発生します。 このイベントのイベント ハンドラーを作成し、選択したロールからユーザーを削除するコードを記述する必要があります。 イベント ハンドラーを作成し、次のコードを追加します。

Protected Sub RolesUserList_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles RolesUserList.RowDeleting 
     ' Get the selected role 
     Dim selectedRoleName As String = RoleList.SelectedValue 
 
     ' Reference the UserNameLabel 
     Dim UserNameLabel As Label = CType(RolesUserList.Rows(e.RowIndex).FindControl("UserNameLabel"),Label) 
 
     ' Remove the user from the role 
     Roles.RemoveUserFromRole(UserNameLabel.Text, selectedRoleName) 
 
     ' Refresh the GridView 
     DisplayUsersBelongingToRole() 
 
     ' Display a status message 
     ActionStatus.Text = String.Format("User {0} was removed from role {1}.", UserNameLabel.Text,selectedRoleName) 
End Sub

コードは、選択したロール名を決定することから始まります。 次に、"削除" ボタンが UserNameLabel クリックされた行からコントロールをプログラムで参照して、削除するユーザーの UserName を決定します。 その後、ユーザーは メソッドの呼び出し Roles.RemoveUserFromRole によってロールから削除されます。 RolesUserListその後、GridView が更新され、Label コントロールを介してメッセージがActionStatus表示されます。

注意

[削除] ボタンでは、ロールからユーザーを削除する前に、ユーザーからの確認は必要ありません。 ユーザー確認のレベルを追加するようお勧めします。 アクションを確認する最も簡単な方法の 1 つは、クライアント側の確認ダイアログ ボックスを使用することです。 この手法の詳細については、「 削除時にClient-Side確認を追加する」を参照してください。

図 8 は、ユーザー Tito が Supervisors グループから削除された後のページを示しています。

悲しいかな、ティトはもはやスーパーバイザーではない

図 8: 悲しいかな、Tito はもはやスーパーバイザーではありません (フルサイズの画像を表示する をクリックします)

選択したロールへの新しいユーザーの追加

選択したロールからユーザーを削除すると共に、このページへの訪問者は、選択したロールにユーザーを追加することもできます。 選択したロールにユーザーを追加するための最適なインターフェイスは、予想されるユーザー アカウントの数によって異なります。 Web サイトに数十個以下のユーザー アカウントしか保存できない場合は、ここで DropDownList を使用できます。 何千ものユーザー アカウントがある場合は、訪問者がアカウントをページングしたり、特定のアカウントを検索したり、他の方法でユーザー アカウントをフィルター処理したりできるようにするユーザー インターフェイスを含めることができます。

このページでは、システム内のユーザー アカウントの数に関係なく動作する非常に単純なインターフェイスを使用しましょう。 つまり、TextBox を使用して、選択したロールに追加するユーザーのユーザー名を入力するようにビジターに求めます。 その名前のユーザーが存在しない場合、またはユーザーが既にロールのメンバーである場合は、Label に ActionStatus メッセージが表示されます。 ただし、ユーザーが存在し、ロールのメンバーでない場合は、ロールに追加してグリッドを更新します。

GridView の下に TextBox と Button を追加します。 TextBox ID の を に UserNameToAddToRole 設定し、Button ID の プロパティと Text プロパティを "ロールに AddUserToRoleButton ユーザーを追加" にそれぞれ設定します。

<p> 
     <b>UserName:</b> 
     <asp:TextBox ID="UserNameToAddToRole" runat="server"></asp:TextBox> 
     <br /> 
     <asp:Button ID="AddUserToRoleButton" runat="server" Text="Add User to Role" /> 
</p>

次に、 の Click イベント ハンドラーを AddUserToRoleButton 作成し、次のコードを追加します。

Protected Sub AddUserToRoleButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AddUserToRoleButton.Click 
     ' Get the selected role and username 
     Dim selectedRoleName As String = RoleList.SelectedValue 
     Dim userToAddToRole As String = UserNameToAddToRole.Text 
 
     ' Make sure that a value was entered 
     If userToAddToRole.Trim().Length = 0 Then 
          ActionStatus.Text = "You must enter a username in the textbox." 
          Exit Sub 
     End If 
 
     ' Make sure that the user exists in the system 
     Dim userInfo As MembershipUser = Membership.GetUser(userToAddToRole) 
     If userInfo Is Nothing Then 
          ActionStatus.Text = String.Format("The user {0} does not exist in the system.",userNameToAddToRole) 
          Exit Sub 
     End If 
 
     ' Make sure that the user doesn't already belong to this role 
     If Roles.IsUserInRole(userToAddToRole, selectedRoleName) Then 
          ActionStatus.Text = String.Format("User {0} already is a member of role {1}.", UserNameToAddToRole,selectedRoleName) 
          Exit Sub 
     End If 
 
     ' If we reach here, we need to add the user to the role 
     Roles.AddUserToRole(userToAddToRole, selectedRoleName) 
 
     ' Clear out the TextBox 
     userNameToAddToRole.Text = String.Empty 
 
     ' Refresh the GridView 
     DisplayUsersBelongingToRole() 
 
     ' Display a status message 
     ActionStatus.Text = String.Format("User {0} was added to role {1}.", UserNameToAddToRole,selectedRoleName) 
End Sub

イベント ハンドラーのコードの大部分は、 Click さまざまな検証チェックを実行します。 これにより、訪問者が TextBox にユーザー名を UserNameToAddToRole 指定し、ユーザーがシステムに存在し、選択したロールにまだ属していないことを確認します。 これらのチェックのいずれかが失敗した場合は、 に ActionStatus 適切なメッセージが表示され、イベント ハンドラーが終了します。 すべてのチェックに合格すると、 メソッドを使用してユーザーがロールに Roles.AddUserToRole 追加されます。 その後、TextBox の Text プロパティがクリアされ、GridView が更新され ActionStatus 、指定したユーザーが選択したロールに正常に追加されたことを示すメッセージが Label に表示されます。

注意

指定したユーザーが選択したロールにまだ属していないことを確認するために、 メソッドをRoles.IsUserInRole(userName, roleName)使用します。このメソッドは、userNameroleName のメンバーであるかどうかを示すブール値を返します。 ロールベースの承認を確認するときは、次の チュートリアル でこの方法をもう一度使用します。

ブラウザーからページにアクセスし、DropDownList から Supervisors ロールを RoleList 選択します。 無効なユーザー名を入力してみてください。ユーザーがシステムに存在しないことを説明するメッセージが表示されます。

存在しないユーザーをロールに追加することはできません

図 9: 存在しないユーザーをロールに追加できません (フルサイズの画像を表示する場合をクリックします)

次に、有効なユーザーを追加してみてください。 先に進み、Tito を Supervisors ロールに再追加します。

ティトは再びスーパーバイザーです!

図 10: ティトはもう一度スーパーバイザーです! (クリックするとフルサイズの画像が表示されます)

手順 3: "By User" インターフェイスと "By Role" インターフェイスをクロス更新する

この UsersAndRoles.aspx ページには、ユーザーとロールを管理するための 2 つの異なるインターフェイスが用意されています。 現在、これら 2 つのインターフェイスは互いに独立して動作するため、一方のインターフェイスで行われた変更が他のインターフェイスにすぐに反映されない可能性があります。 たとえば、ページの訪問者が DropDownList から Supervisors ロールを RoleList 選択するとします。このロールには、Bruce と Tito がメンバーとして一覧表示されます。 次に、訪問者は DropDownList から UserList Tito を選択し、Repeater の [Administrators and Supervisors]\(管理者とスーパーバイザー\) チェックボックスを UsersRoleList オンにします。 その後、訪問者が Repeater から Supervisor ロールをオフにした場合、Tito は Supervisors ロールから削除されますが、この変更は "by role" インターフェイスには反映されません。 GridView は引き続き Tito を Supervisors ロールのメンバーとして表示します。

これを修正するには、ロールが Repeater でオンまたはオフになっている場合は常に GridView を更新する UsersRoleList 必要があります。 同様に、ユーザーが "by role" インターフェイスからロールに削除または追加されるたびに、Repeater を更新する必要があります。

"by user" インターフェイスの Repeater は、 メソッドを CheckRolesForSelectedUser 呼び出すことによって更新されます。 "ロール別" インターフェイスは、GridView RowDeletingRolesUserListイベント ハンドラーと Button Click のイベント ハンドラーでAddUserToRoleButton変更できます。 したがって、これらの各メソッドから メソッドを CheckRolesForSelectedUser 呼び出す必要があります。

Protected Sub RolesUserList_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles RolesUserList.RowDeleting 
     ... Code removed for brevity ... 
 
     ' Refresh the "by user" interface 
     CheckRolesForSelectedUser() 
End Sub 
 
Protected Sub AddUserToRoleButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AddUserToRoleButton.Click 
     ... Code removed for brevity ... 
 
     ' Refresh the "by user" interface 
     CheckRolesForSelectedUser() 
End Sub

同様に、"by role" インターフェイスの GridView は メソッドを DisplayUsersBelongingToRole 呼び出すことによって更新され、"by user" インターフェイスはイベント ハンドラーを RoleCheckBox_CheckChanged 介して変更されます。 そのため、このイベント ハンドラーから メソッドを DisplayUsersBelongingToRole 呼び出す必要があります。

Protected Sub RoleCheckBox_CheckChanged(ByVal sender As Object, ByVal e As EventArgs) 
     ... Code removed for brevity ... 
 
     ' Refresh the "by role" interface 
     DisplayUsersBelongingToRole() 
End Sub

これらのマイナー コードの変更により、"by user" インターフェイスと "by role" インターフェイスが正しくクロス更新されるようになりました。 これを確認するには、ブラウザーからページにアクセスし、 と DropDownLists から UserList Tito と RoleList Supervisors をそれぞれ選択します。 "by user" インターフェイスの Repeater から Tito の Supervisors ロールをオフにすると、Tito は "by role" インターフェイスの GridView から自動的に削除されることに注意してください。 "by role" インターフェイスから Supervisors ロールに Tito を追加すると、"by user" インターフェイスの Supervisors チェックボックスが自動的に再チェックされます。

手順 4: CreateUserWizard をカスタマイズして "ロールの指定" ステップを含める

ユーザー アカウント作成チュートリアルでは、CreateUserWizard Web コントロールを使用して、新しいユーザー アカウントを作成するためのインターフェイスを提供する方法について説明しました。 CreateUserWizard コントロールは、次の 2 つの方法のいずれかで使用できます。

  • 訪問者がサイトで独自のユーザー アカウントを作成するための手段として、
  • 管理者が新しいアカウントを作成する手段として

最初のユース ケースでは、訪問者がサイトに来て CreateUserWizard に入力し、サイトに登録するために情報を入力します。 2 番目のケースでは、管理者が別のユーザーの新しいアカウントを作成します。

管理者が他のユーザーのアカウントを作成する場合は、管理者が新しいユーザー アカウントが属するロールを指定できるようにすると便利な場合があります。 追加のユーザー情報格納に関するチュートリアルでは、 を追加WizardStepsして CreateUserWizard をカスタマイズする方法を確認しました。 新しいユーザーのロールを指定するために、CreateUserWizard に追加の手順を追加する方法を見てみましょう。

ページを CreateUserWizardWithRoles.aspx 開き、 という名前 RegisterUserWithRolesの CreateUserWizard コントロールを追加します。 コントロールの ContinueDestinationPageUrl プロパティを "~/Default.aspx" に設定します。 ここでの考え方は、管理者がこの CreateUserWizard コントロールを使用して新しいユーザー アカウントを作成するため、コントロールの LoginCreatedUser プロパティを False に設定します。 このプロパティは LoginCreatedUser 、作成したばかりのユーザーとして訪問者が自動的にログオンするかどうかを指定し、既定値は True です。 管理者が新しいアカウントを作成するときに、自分としてサインインしたままにしておく必要があるため、False に設定します。

次に、[追加/削除 WizardSteps] を選択します。オプションを選択し、新しい WizardStepを追加し、 を ID に設定します SpecifyRolesStepSpecifyRolesStep WizardStepを移動して、"新しいアカウントにサインアップする" ステップの後、"完了" ステップの前に移動します。 の プロパティを WizardStep"ロールの Title 指定" に設定し、その StepType プロパティを に Step設定し、その AllowReturn プロパティを False に設定します。

[ウィザード ステップ コレクション エディター] ウィンドウで選択した [ロールの指定] プロパティを示すスクリーンショット。

図 11: CreateUserWizard に "ロールの指定" WizardStep を追加します (フルサイズの画像を表示するには、ここをクリックします)

この変更後、CreateUserWizard の宣言型マークアップは次のようになります。

<asp:CreateUserWizard ID="RegisterUserWithRoles" runat="server" 
     ContinueDestinationPageUrl="~/Default.aspx" LoginCreatedUser="False"> 
     <WizardSteps> 
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server"> 
          </asp:CreateUserWizardStep> 
          <asp:WizardStep ID="SpecifyRolesStep" runat="server" StepType="Step" 
               Title="Specify Roles" AllowReturn="False"> 
          </asp:WizardStep> 
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server"> 
          </asp:CompleteWizardStep> 
     </WizardSteps> 
</asp:CreateUserWizard>

[ロールWizardStepの指定] で、この CheckBoxList という名前RoleList.の CheckBoxList を追加すると、使用可能なロールが一覧表示されます。これにより、ページにアクセスするユーザーは、新しく作成されたユーザーが属するロールをチェックできます。

2 つのコーディング タスクが残されています。最初に、CheckBoxList にシステム内のロールを設定 RoleList する必要があります。2 つ目は、ユーザーが [ロールの指定] ステップから [完了] ステップに移動したときに、選択したロールに作成されたユーザーを追加する必要があります。 イベント ハンドラーで最初のタスクを Page_Load 実行できます。 次のコードは、ページへの最初の RoleList アクセス時に CheckBox をプログラムで参照し、システム内のロールをそのページにバインドします。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Reference the SpecifyRolesStep WizardStep 
          Dim SpecifyRolesStep As WizardStep = CType(RegisterUserWithRoles.FindControl("SpecifyRolesStep"),WizardStep) 
 
          ' Reference the RoleList CheckBoxList 
          Dim RoleList As CheckBoxList = CType(SpecifyRolesStep.FindControl("RoleList"), CheckBoxList) 
 
          ' Bind the set of roles to RoleList 
          RoleList.DataSource = Roles.GetAllRoles() 
          RoleList.DataBind() 
     End If 
End Sub

上記のコードは使い慣れているはずです。 追加のユーザー情報格納に関するチュートリアルでは、カスタム 内から Web コントロールを参照するために 2 つのFindControlステートメントを使用しましたWizardStep。 また、ロールを CheckBoxList にバインドするコードは、このチュートリアルの前半から取得しました。

2 番目のプログラミング タスクを実行するには、"ロールの指定" ステップがいつ完了したかを把握する必要があります。 CreateUserWizard には ActiveStepChanged イベントがあり、訪問者が 1 つのステップから別のステップに移動するたびに発生することを思い出してください。 ここでは、ユーザーが "完了" ステップに達したかどうかを確認できます。その場合は、選択したロールにユーザーを追加する必要があります。

イベントのイベント ハンドラーを ActiveStepChanged 作成し、次のコードを追加します。

Protected Sub RegisterUserWithRoles_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RegisterUserWithRoles.ActiveStepChanged 
     'Have we JUST reached the Complete step? 
     If RegisterUserWithRoles.ActiveStep.Title = "Complete" Then 
          ' Reference the SpecifyRolesStep WizardStep 
          Dim SpecifyRolesStep As WizardStep = CType(RegisterUserWithRoles.FindControl("SpecifyRolesStep"),WizardStep) 
 
          ' Reference the RoleList CheckBoxList 
          Dim RoleList As CheckBoxList = CType(SpecifyRolesStep.FindControl("RoleList"), CheckBoxList) 
 
          ' Add the checked roles to the just-added user 
          For Each li As ListItem In RoleList.Items 
               If li.Selected Then 
                    Roles.AddUserToRole(RegisterUserWithRoles.UserName, li.Text) 
               End If 
          Next 
     End If 
End Sub

ユーザーが "完了" ステップに到達したばかりの場合、イベント ハンドラーは CheckBoxList の項目を RoleList 列挙し、作成したユーザーが選択したロールに割り当てられます。

ブラウザーからこのページにアクセスします。 CreateUserWizard の最初の手順は、新しいユーザーのユーザー名、パスワード、電子メール、およびその他のキー情報の入力を求める標準の "新しいアカウントへのサインアップ" ステップです。 情報を入力して、Wanda という名前の新しいユーザーを作成します。

Wanda という名前の新しいユーザーを作成する

図 12: Wanda という名前の新しいユーザーを作成する (フルサイズの画像を表示する をクリックします)

[ユーザーの作成] ボタンをクリックします。 CreateUserWizard は内部的に メソッドを Membership.CreateUser 呼び出し、新しいユーザー アカウントを作成し、次の手順である "ロールの指定" に進みます。ここでは、システムロールが一覧表示されます。 [Supervisors]\(スーパーバイザー\) チェックボックスをオンにし、[Next]\(次へ\) をクリックします。

Wanda をスーパーバイザー ロールのメンバーにする

図 13: Wanda をスーパーバイザー ロールのメンバーにする (フルサイズの画像を表示する をクリックします)

[次へ] をクリックするとポストバックが発生し、 が ActiveStep "完了" ステップに更新されます。 ActiveStepChangedイベント ハンドラーでは、最近作成したユーザー アカウントが Supervisors ロールに割り当てられます。 これを確認するには、ページに UsersAndRoles.aspx 戻り、DropDownList から Supervisors を RoleList 選択します。 図 14 に示すように、スーパーバイザーは現在、Bruce、Tito、Wanda の 3 人のユーザーで構成されています。

Bruce、Tito、Wanda はすべてスーパーバイザーです

図 14: Bruce、Tito、Wanda はすべてスーパーバイザーです (フルサイズの画像を表示する をクリックします)

まとめ

Roles フレームワークには、特定のユーザーのロールに関する情報を取得するためのメソッドと、指定したロールに属しているユーザーを決定するためのメソッドが用意されています。 さらに、1 つ以上のユーザーを 1 つ以上のロールに追加および削除する方法がいくつかあります。 このチュートリアルでは、 と RemoveUserFromRoleの 2 つの方法に焦点をAddUserToRole当てています。 1 つのロールに複数のユーザーを追加し、1 人のユーザーに複数のロールを割り当てるために設計された追加のバリエーションがあります。

このチュートリアルでは、CreateUserWizard コントロールを拡張して、 を含 WizardStep め、新しく作成されたユーザーのロールを指定する方法についても説明しました。 このような手順は、管理者が新しいユーザーのユーザー アカウントを作成するプロセスを効率化するのに役立ちます。

この時点で、ロールを作成および削除する方法と、ロールに対してユーザーを追加および削除する方法について説明しました。 ただし、ロールベースの承認の適用はまだ見ていません。 次の チュートリアル では、ロールごとに URL 承認規則を定義する方法と、現在ログインしているユーザーのロールに基づいてページ レベルの機能を制限する方法について説明します。

プログラミングに満足!

もっと読む

このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。

著者について

複数の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 Scott は、 または mitchell@4guysfromrolla.com のブログから http://ScottOnWriting.NETアクセスできます。

特別な感謝...

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリードレビュー担当者はテレサ・マーフィーでした。 今後の MSDN の記事を確認することに関心がありますか? もしそうなら、私に行を落としてください mitchell@4GuysFromRolla.com