ユーザーにロールを割り当てる (VB)
注意
この記事が作成されて以来、ASP.NET メンバーシップ プロバイダーは ASP.NET Identity に置き換えられました。 この記事の執筆時点で取り上げられたメンバーシップ プロバイダーではなく 、ASP.NET ID プラットフォームを使用するようにアプリを更新することを強くお勧めします。 ASP.NET ID には、ASP.NET メンバーシップ システムに比して、次のような多くの利点があります。
- パフォーマンスの向上
- 拡張性とテスト性の向上
- OAuth、OpenID Connect、および 2 要素認証のサポート
- クレームベースの ID のサポート
- ASP.Net Core との相互運用性の向上
このチュートリアルでは、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によるこの効果を示しています。
図 1: ラベルのプロパティの CssClass
結果が大きく、赤いフォントになります (フルサイズの画像を表示するにはクリックします)
次に、ページに DropDownList を追加し、そのプロパティを ID
に UserList
設定し、そのプロパティを 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
、、Email
CreationDate
IsOnline
、、 など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
の イベントにCheckedChanged
RoleCheckBox
結び付けます。
<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 を追加します。
図 3: Tito が管理者と監督者の役割に追加されました (フルサイズの画像を表示する をクリックします)
次に、ドロップダウン リストからユーザー Bruce を選択します。 ポストバックがあり、Repeater の CheckBox が を CheckRolesForSelectedUser
介して更新されます。 Bruce はまだロールに属していないため、2 つのチェック ボックスはオフになっています。 次に、Bruce を Supervisors ロールに追加します。
図 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" に設定します。 という名前UserNameLabel
の ItemTemplate
Label プロパティに databinding 式Container.DataItem
Text
の値を表示するように 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 は、ブラウザーを使用して表示した場合の最終結果を示しています。ドロップダウン リストには、システムの役割が設定されています。
図 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 つのメンバーで構成されています。
図 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)
使用します。このメソッドは、userName が roleName のメンバーであるかどうかを示すブール値を返します。 ロールベースの承認を確認するときは、次の チュートリアル でこの方法をもう一度使用します。
ブラウザーからページにアクセスし、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 RowDeleting
のRolesUserList
イベント ハンドラーと 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
に設定します SpecifyRolesStep
。 SpecifyRolesStep 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 という名前の新しいユーザーを作成します。
図 12: Wanda という名前の新しいユーザーを作成する (フルサイズの画像を表示する をクリックします)
[ユーザーの作成] ボタンをクリックします。 CreateUserWizard は内部的に メソッドを Membership.CreateUser
呼び出し、新しいユーザー アカウントを作成し、次の手順である "ロールの指定" に進みます。ここでは、システムロールが一覧表示されます。 [Supervisors]\(スーパーバイザー\) チェックボックスをオンにし、[Next]\(次へ\) をクリックします。
図 13: Wanda をスーパーバイザー ロールのメンバーにする (フルサイズの画像を表示する をクリックします)
[次へ] をクリックするとポストバックが発生し、 が ActiveStep
"完了" ステップに更新されます。 ActiveStepChanged
イベント ハンドラーでは、最近作成したユーザー アカウントが Supervisors ロールに割り当てられます。 これを確認するには、ページに UsersAndRoles.aspx
戻り、DropDownList から Supervisors を RoleList
選択します。 図 14 に示すように、スーパーバイザーは現在、Bruce、Tito、Wanda の 3 人のユーザーで構成されています。
図 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
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示