ユーザーにロールを割り当てる (C#)
注意
この記事が作成されて以来、ASP.NET メンバーシップ プロバイダーは 、ASP.NET ID に置き換えられました。 この記事の執筆時点で取り上げられたメンバーシップ プロバイダーではなく 、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 つの方法があります。訪問者がロールを選択し、そのロールに属するすべてのユーザーを表示したり ("ロール別" 表示)、訪問者にユーザーの選択を求め、そのユーザーに割り当てられたロール ("ユーザー別" 表示) を表示することもできます。
"ロール別" ビューは、訪問者が特定のロールに属するユーザーのセットを知りたい場合に役立ちます。"ユーザー別" ビューは、訪問者が特定のユーザーのロールを知る必要がある場合に最適です。 ページに "ロール別" インターフェイスと "ユーザー別" インターフェイスの両方を含めてみましょう。
まず、"ユーザー別" インターフェイスの作成から始めます。 このインターフェイスは、ドロップダウン リストとチェックボックスの一覧で構成されます。 ドロップダウン リストには、システム内のユーザーのセットが設定されます。チェック ボックスはロールを列挙します。 ドロップダウン リストからユーザーを選択すると、ユーザーが属しているロールがチェックされます。 ページにアクセスするユーザーは、チェックボックスをチェックまたはオフにして、選択したユーザーを対応するロールに追加または削除できます。
注意
ドロップダウン リストを使用してユーザー アカウントを一覧表示することは、何百ものユーザー アカウントがある可能性がある Web サイトには最適な選択肢ではありません。 ドロップダウン リストは、ユーザーが比較的短いオプションの一覧から 1 つの項目を選択できるように設計されています。 リスト アイテムの数が増えるにつれて、すぐに扱いにくくなります。 多数のユーザー アカウントを持つ可能性のある Web サイトを構築する場合は、ページング可能な GridView やフィルター可能なインターフェイスなどの代替ユーザー インターフェイスを使用することを検討してください。このインターフェイスには、訪問者にレターの選択を求めるメッセージが表示され、ユーザー名が選択した文字で始まるユーザーのみが表示されます。
手順 1: "ユーザー別" ユーザー インターフェイスの構築
ページを UsersAndRoles.aspx
開きます。 ページの上部に、 という名前 ActionStatus
の Label Web コントロールを追加し、そのプロパティを Text
クリアします。 このラベルを使用して、実行されたアクションに関するフィードバックを提供し、"User Tito has added to the Administrators role"、または "User Jisun has removed from the Supervisors role" などのメッセージを表示します。これらのメッセージを目立たせるために、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 void BindUsersToUserList()
{
// Get all of the user accounts
MembershipUserCollection users = Membership.GetAllUsers();
UserList.DataSource = users;
UserList.DataBind();
}
private void BindRolesToList()
{
// Get all of the roles
string[] roles = Roles.GetAllRoles();
UsersRoleList.DataSource = roles;
UsersRoleList.DataBind();
}
メソッドはBindUsersToUserList
、 メソッドを使用してシステム内のすべてのユーザー アカウントをMembership.GetAllUsers
取得します。 これにより、インスタンスのMembershipUserCollection
コレクションMembershipUser
である オブジェクトが返されます。 その後、このコレクションは DropDownList に UserList
バインドされます。 MembershipUser
コレクションを構成するインスタンスには、、Email
CreationDate
IsOnline
、、 などUserName
、さまざまなプロパティが含まれています。 DropDownList にプロパティのUserName
値を表示するように指示するには、DropDownList DataTextField
の プロパティとDataValueField
プロパティが "UserName" に設定されていることを確認UserList
します。
注意
Membership.GetAllUsers
メソッドには 2 つのオーバーロードがあります。1 つは入力パラメーターを受け取らず、すべてのユーザーを返し、1 つはページ インデックスとページ サイズの整数値を受け取り、指定されたユーザーのサブセットのみを返します。 ページング可能なユーザー インターフェイス要素に大量のユーザー アカウントが表示されている場合、2 番目のオーバーロードを使用すると、すべてのユーザー アカウントではなく、ユーザー アカウントの正確なサブセットのみが返されるため、ユーザーを効率的にページングできます。
メソッドはBindRolesToList
、 クラスの GetAllRoles
メソッドをRoles
呼び出すことから始まります。このメソッドは、システム内のロールを含む文字列配列を返します。 その後、この文字列配列は Repeater にバインドされます。
最後に、ページが最初に読み込まれるときに、これら 2 つのメソッドを呼び出す必要があります。 Page_Load
イベント ハンドラーに次のコードを追加します。
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Bind the users and roles
BindUsersToUserList();
BindRolesToList();
}
}
このコードを配置した状態で、ブラウザーからページにアクセスしてください。画面は図 2 のようになります。 すべてのユーザー アカウントがドロップダウン リストに入力され、その下に各ロールがチェックボックスとして表示されます。 DropDownList と CheckBoxes のプロパティを True に設定 AutoPostBack
しているため、選択したユーザーを変更するか、ロールをオンまたはオフにするとポストバックが発生します。 ただし、これらのアクションを処理するコードをまだ記述していないため、アクションは実行されません。 これらのタスクは、次の 2 つのセクションで取り組みます。
図 2: ページにユーザーとロールが表示されます (クリックするとフルサイズの画像が表示されます)
選択したユーザーが属しているロールの確認
ページが最初に読み込まれるとき、または訪問者がドロップダウン リストから新しいユーザーを選択するたびに、選択したユーザーがそのロールに属している場合にのみ特定のロールチェックボックスがオンになるように、チェックボックスを更新 UsersRoleList
する必要があります。 これを実現するには、次のコードを使用して という名前 CheckRolesForSelectedUser
のメソッドを作成します。
private void CheckRolesForSelectedUser()
{
// Determine what roles the selected user belongs to
string selectedUserName = UserList.SelectedValue;
string[] selectedUsersRoles = Roles.GetRolesForUser(selectedUserName);
// Loop through the Repeater's Items and check or uncheck the checkbox as needed
foreach (RepeaterItem ri in UsersRoleList.Items)
{
// Programmatically reference the CheckBox
CheckBox RoleCheckBox = ri.FindControl("RoleCheckBox") as CheckBox;
// See if RoleCheckBox.Text is in selectedUsersRoles
if (selectedUsersRoles.Contains<string>(RoleCheckBox.Text))
RoleCheckBox.Checked = true;
else
RoleCheckBox.Checked = false;
}
}
上記のコードは、選択したユーザーが誰であるかを判断することから始まります。 次に、Roles クラスの GetRolesForUser(userName)
メソッド を使用して、指定したユーザーのロールのセットを文字列配列として返します。 次に、Repeater の項目が列挙され、各項目の RoleCheckBox
CheckBox がプログラムによって参照されます。 CheckBox は、対応するロールが文字列配列内 selectedUsersRoles
に含まれている場合にのみチェックされます。
注意
selectedUserRoles.Contains<string>(...)
バージョン 2.0 ASP.NET 使用している場合、構文はコンパイルされません。 メソッドは Contains<string>
LINQ ライブラリの一部であり、ASP.NET 3.5 の新機能です。 まだバージョン 2.0 ASP.NET 使用している場合は、代わりに メソッドをArray.IndexOf<string>
使用します。
メソッドは CheckRolesForSelectedUser
、ページが最初に読み込まれるときと、DropDownList の選択したインデックスが変更されるたびに UserList
、2 つの場合に呼び出す必要があります。 そのため、イベント ハンドラーからこのメソッドを Page_Load
呼び出します (および の BindUsersToUserList
呼び出し BindRolesToList
の後)。 また、DropDownList SelectedIndexChanged
のイベントのイベント ハンドラーを作成し、そこからこのメソッドを呼び出します。
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Bind the users and roles
BindUsersToUserList();
BindRolesToList();
// Check the selected user's roles
CheckRolesForSelectedUser();
}
}
...
protected void UserList_SelectedIndexChanged(object sender, EventArgs e)
{
CheckRolesForSelectedUser();
}
このコードを配置すると、ブラウザーを使用してページをテストできます。 ただし、ページには UsersAndRoles.aspx
現在、ユーザーをロールに割り当てる機能がないため、ロールを持つユーザーはいません。 ユーザーをロールに割り当てるためのインターフェイスをすぐに作成するので、このコードが機能することを私の言葉で確認し、後でそうすることを確認するか、この機能を今すぐテストするためにレコードをテーブルに aspnet_UsersInRoles
挿入してユーザーをロールに手動で追加できます。
ロールへのユーザーの割り当てと削除
訪問者が Repeater で UsersRoleList
CheckBox をチェックまたはオフにした場合は、選択したユーザーを対応するロールに追加または削除する必要があります。 CheckBox の AutoPostBack
プロパティは現在 True に設定されています。これにより、Repeater の CheckBox がオンまたはオフの場合は、いつでもポストバックが発生します。 要するに、CheckBox CheckChanged
のイベントのイベント ハンドラーを作成する必要があります。 CheckBox は Repeater コントロール内にあるため、イベント ハンドラーのプラミングを手動で追加する必要があります。 まず、次のように、分離コード クラスにメソッドとしてイベント ハンドラーを protected
追加します。
protected void RoleCheckBox_CheckChanged(object sender, EventArgs e)
{
}
に戻り、このイベント ハンドラーのコードをしばらく書き込みます。 しかし、まず、イベント処理のプラミングを完了しましょう。 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 インスタンスは、その プロパティと Checked
プロパティを介してチェックまたはオフにされたロールをText
示します。 この情報を選択したユーザーの UserName と共に使用して、クラスAddUserToRole
または メソッドを使用してロールに対してユーザーをRoles
追加またはRemoveUserFromRole
削除します。
protected void RoleCheckBox_CheckChanged(object sender, EventArgs e)
{
// Reference the CheckBox that raised this event
CheckBox RoleCheckBox = sender as CheckBox;
// Get the currently selected user and role
string selectedUserName = UserList.SelectedValue;
string roleName = RoleCheckBox.Text;
// Determine if we need to add or remove the user from this role
if (RoleCheckBox.Checked)
{
// 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);
}
}
上記のコードは、イベントを発生させた CheckBox をプログラムで参照することから始まります。これは、入力パラメーターを sender
介して使用できます。 CheckBox をオンにすると、選択したユーザーが指定したロールに追加され、それ以外の場合はロールから削除されます。 いずれの場合も、[ラベル] ActionStatus
には、実行したアクションを要約したメッセージが表示されます。
ブラウザーを使用してこのページをテストしてください。 [ユーザー Tito] を選択し、[管理者] ロールと [Supervisors] ロールの両方に Tito を追加します。
図 3: Tito が管理者と監督者の役割に追加されました (フルサイズの画像を表示する をクリックします)
次に、ドロップダウン リストからユーザー Bruce を選択します。 ポストバックがあり、Repeater の CheckBox は を CheckRolesForSelectedUser
介して更新されます。 Bruce はまだロールに属していないため、2 つのチェック ボックスはオフになっています。 次に、Supervisors ロールに Bruce を追加します。
図 4: Bruce が Supervisors ロールに追加されました (フルサイズの画像を表示する をクリックします)
メソッドの CheckRolesForSelectedUser
機能をさらに確認するには、Tito または Bruce 以外のユーザーを選択します。 チェック ボックスが自動的にオフになっていることに注意してください。これは、どのロールにも属していない点に注意してください。 Tito に戻ります。 [管理者] と [スーパーバイザー] の両方のチェック ボックスをオンにする必要があります。
手順 2: "ロール別" ユーザー インターフェイスの構築
この時点で、"by users" インターフェイスを完了し、"ロール別" インターフェイスへの取り組みを開始する準備ができました。 "ロール別" インターフェイスは、ドロップダウン リストからロールを選択するようにユーザーに求め、そのロールに属するユーザーのセットを GridView に表示します。
別の DropDownList コントロールをページに UsersAndRoles.aspx
追加します。 この 1 つを Repeater コントロールの下に配置し、 という名前を付け RoleList
、そのプロパティを AutoPostBack
True に設定します。 その下に GridView を追加し、 という名前を付けます RolesUserList
。 この GridView には、選択したロールに属しているユーザーが一覧表示されます。 GridView の AutoGenerateColumns
プロパティを False に設定し、TemplateField をグリッドの Columns
コレクションに追加し、その HeaderText
プロパティを "Users" に設定します。 という名前UserNameLabel
の ItemTemplate
Label の プロパティに databinding 式Container.DataItem
Text
の値を表示するように TemplateField を定義します。
GridView を追加して構成した後、"by role" インターフェイスの宣言型マークアップは次のようになります。
<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>
システム内のロールのセットを RoleList
DropDownList に設定する必要があります。 これを実現するには、 メソッドを更新して BindRolesToList
、 メソッドによって返される文字列配列を Roles.GetAllRoles
RolesList
DropDownList (および Repeater) に UsersRoleList
バインドします。
private void BindRolesToList()
{
// Get all of the roles
string[] roles = Roles.GetAllRoles();
UsersRoleList.DataSource = roles;
UsersRoleList.DataBind();
RoleList.DataSource = roles;
RoleList.DataBind();
}
メソッドの最後の BindRolesToList
2 行が追加され、ロールのセットが DropDownList コントロールに RoleList
バインドされました。 図 5 は、ブラウザーを使用して表示したときの最終的な結果を示しています。ドロップダウン リストには、システムの役割が入力されています。
図 5: ロールが DropDownList に RoleList
表示される (フルサイズの画像を表示するをクリックします)
選択したロールに属するユーザーの表示
ページが最初に読み込まれるとき、または DropDownList から RoleList
新しいロールが選択されたときに、そのロールに属するユーザーの一覧を GridView に表示する必要があります。 次のコードを使用して、 という名前 DisplayUsersBelongingToRole
のメソッドを作成します。
private void DisplayUsersBelongingToRole()
{
// Get the selected role
string selectedRoleName = RoleList.SelectedValue;
// Get the list of usernames that belong to the role
string[] usersBelongingToRole = Roles.GetUsersInRole(selectedRoleName);
// Bind the list of users to the GridView
RolesUserList.DataSource = usersBelongingToRole;
RolesUserList.DataBind();
}
このメソッドは、最初に DropDownList から選択したロールを RoleList
取得します。 次に、 メソッドをRoles.GetUsersInRole(roleName)
使用して、そのロールに属するユーザーの UserNames の文字列配列を取得します。 その後、この配列は GridView に RolesUserList
バインドされます。
このメソッドは、ページが最初に読み込まれるときと、DropDownList で選択したロールが変更されたときの 2 つの状況で呼び出す RoleList
必要があります。 そのため、 の呼び出し後に Page_Load
このメソッドが呼び出されるように、イベント ハンドラーを更新します CheckRolesForSelectedUser
。 次に、 の イベントのイベント ハンドラーをRoleList
SelectedIndexChanged
作成し、そこからこのメソッドも呼び出します。
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Bind the users and roles
BindUsersToUserList();
BindRolesToList();
// Check the selected user's roles
CheckRolesForSelectedUser();
// Display those users belonging to the currently selected role
DisplayUsersBelongingToRole();
}
}
...
protected void RoleList_SelectedIndexChanged(object sender, EventArgs e)
{
DisplayUsersBelongingToRole();
}
このコードを配置すると、GridView には、 RolesUserList
選択したロールに属しているユーザーが表示されます。 図 6 に示すように、Supervisors ロールは、Bruce と Tito の 2 つのメンバーで構成されています。
図 6: GridView には、選択したロールに属しているユーザーが一覧表示されます (フルサイズの画像を表示する をクリックします)
選択したロールからのユーザーの削除
"削除" ボタンの RolesUserList
列が含まれるように GridView を拡張してみましょう。 特定のユーザーの [削除] ボタンをクリックすると、そのロールから削除されます。
まず、GridView に [削除] ボタン フィールドを追加します。 このフィールドを最も左のファイルとして表示し、そのプロパティを DeleteText
"Delete" (既定値) から "Remove" に変更します。
図 7: GridView に [削除] ボタンを追加します (フルサイズの画像を表示する場合をクリックします)
[削除] ボタンをクリックするとポストバックが続き、GridView の RowDeleting
イベントが発生します。 このイベントのイベント ハンドラーを作成し、選択したロールからユーザーを削除するコードを記述する必要があります。 イベント ハンドラーを作成し、次のコードを追加します。
protected void RolesUserList_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
// Get the selected role
string selectedRoleName = RoleList.SelectedValue;
// Reference the UserNameLabel
Label UserNameLabel = RolesUserList.Rows[e.RowIndex].FindControl("UserNameLabel") as 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);
}
コードは、選択したロール名を決定することから始まります。 次に、"削除" ボタンがクリックされた行からコントロールをプログラムで参照 UserNameLabel
して、削除するユーザーの UserName を決定します。 その後、ユーザーは メソッドの呼び出し Roles.RemoveUserFromRole
によってロールから削除されます。 RolesUserList
その後、GridView が更新され、Label コントロールを介してメッセージがActionStatus
表示されます。
注意
[削除] ボタンでは、ロールからユーザーを削除する前に、ユーザーからの確認は必要ありません。 何らかのレベルのユーザー確認を追加するようお勧めします。 アクションを確認する最も簡単な方法の 1 つは、クライアント側の確認ダイアログ ボックスを使用することです。 この手法の詳細については、「 削除時のClient-Side確認の追加」を参照してください。
図 8 は、ユーザー Tito が Supervisors グループから削除された後のページを示しています。
図 8: アラス、ティトはもはやスーパーバイザーではありません (フルサイズの画像を表示する をクリックします)
選択したロールへの新しいユーザーの追加
選択したロールからユーザーを削除すると共に、このページの訪問者は、選択したロールにユーザーを追加することもできます。 選択したロールにユーザーを追加するための最適なインターフェイスは、使用するユーザー アカウントの数によって異なります。 Web サイトに数十個以下のユーザー アカウントが含まれていることがある場合は、ここで DropDownList を使用できます。 何千ものユーザー アカウントがある場合は、訪問者がアカウントをページングしたり、特定のアカウントを検索したり、他の方法でユーザー アカウントをフィルター処理したりできるようにするユーザー インターフェイスを含めることができます。
このページでは、システム内のユーザー アカウントの数に関係なく動作する非常に単純なインターフェイスを使用しましょう。 つまり、TextBox を使用して、選択したロールに追加するユーザーのユーザー名を入力するように訪問者に求めます。 その名前のユーザーが存在しない場合、またはユーザーが既にロールのメンバーである場合は、[ラベル] に ActionStatus
メッセージが表示されます。 ただし、ユーザーが存在し、ロールのメンバーでない場合は、そのユーザーをロールに追加し、グリッドを更新します。
GridView の下に TextBox とボタンを追加します。 TextBox ID
の を にUserNameToAddToRole
設定し、Button ID
の プロパティと プロパティをそれぞれ AddUserToRoleButton
に設定しText
、それぞれ "ロールにユーザーを追加" に設定します。
<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 void AddUserToRoleButton_Click(object sender, EventArgs e)
{
// Get the selected role and username
string selectedRoleName = RoleList.SelectedValue;
string userNameToAddToRole = UserNameToAddToRole.Text;
// Make sure that a value was entered
if (userNameToAddToRole.Trim().Length == 0)
{
ActionStatus.Text = "You must enter a username in the textbox.";
return;
}
// Make sure that the user exists in the system
MembershipUser userInfo = Membership.GetUser(userNameToAddToRole);
if (userInfo == null)
{
ActionStatus.Text = string.Format("The user {0} does not exist in the system.", userNameToAddToRole);
return;
}
// Make sure that the user doesn't already belong to this role
if (Roles.IsUserInRole(userNameToAddToRole, selectedRoleName))
{
ActionStatus.Text = string.Format("User {0} already is a member of role {1}.", userNameToAddToRole, selectedRoleName);
return;
}
// If we reach here, we need to add the user to the role
Roles.AddUserToRole(userNameToAddToRole, 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); }
イベント ハンドラーのコードの大部分は、 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 void RolesUserList_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
... Code removed for brevity ...
// Refresh the "by user" interface
CheckRolesForSelectedUser();
}
protected void AddUserToRoleButton_Click(object sender, EventArgs e)
{
... Code removed for brevity ...
// Refresh the "by user" interface
CheckRolesForSelectedUser();
}
同様に、"by role" インターフェイスの GridView は メソッドを DisplayUsersBelongingToRole
呼び出すことによって更新され、"by user" インターフェイスはイベント ハンドラーを RoleCheckBox_CheckChanged
介して変更されます。 そのため、このイベント ハンドラーから メソッドを DisplayUsersBelongingToRole
呼び出す必要があります。
protected void RoleCheckBox_CheckChanged(object sender, EventArgs e)
{
... Code removed for brevity...
// Refresh the "by role" interface
DisplayUsersBelongingToRole();
}
これらのマイナー コードの変更により、"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
の指定] で、 という名前 RoleList
の CheckBoxList を追加します。 この CheckBoxList には、使用可能なロールが一覧表示され、ページにアクセスするユーザーが、新しく作成されたユーザーが属するロールをチェックできるようになります。
2 つのコーディング タスクが残されています。最初に、CheckBoxList にシステム内のロールを設定 RoleList
する必要があります。2 つ目は、ユーザーが [ロールの指定] ステップから [完了] ステップに移動したときに、選択したロールに作成されたユーザーを追加する必要があります。 イベント ハンドラーで最初のタスクを Page_Load
実行できます。 次のコードは、ページへの最初の RoleList
アクセス時に CheckBox をプログラムで参照し、システム内のロールをそのページにバインドします。
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Reference the SpecifyRolesStep WizardStep
WizardStep SpecifyRolesStep = RegisterUserWithRoles.FindControl("SpecifyRolesStep") as WizardStep;
// Reference the RoleList CheckBoxList
CheckBoxList RoleList = SpecifyRolesStep.FindControl("RoleList") as CheckBoxList;
// Bind the set of roles to RoleList
RoleList.DataSource = Roles.GetAllRoles();
RoleList.DataBind();
}
}
上記のコードは使い慣れているはずです。 追加のユーザー情報の格納に関するチュートリアルでは、カスタム 内から Web コントロールを参照するために 2 つのFindControl
ステートメントを使用しましたWizardStep
。 また、ロールを CheckBoxList にバインドするコードは、このチュートリアルの前半から取得しました。
2 番目のプログラミング タスクを実行するには、"ロールの指定" ステップがいつ完了したかを把握する必要があります。 CreateUserWizard には ActiveStepChanged
イベントがあり、訪問者が 1 つのステップから別のステップに移動するたびに発生することを思い出してください。 ここでは、ユーザーが "完了" ステップに達したかどうかを確認できます。その場合は、選択したロールにユーザーを追加する必要があります。
イベントのイベント ハンドラーを ActiveStepChanged
作成し、次のコードを追加します。
protected void RegisterUserWithRoles_ActiveStepChanged(object sender, EventArgs e)
{
// Have we JUST reached the Complete step?
if (RegisterUserWithRoles.ActiveStep.Title == "Complete")
{
// Reference the SpecifyRolesStep WizardStep
WizardStep SpecifyRolesStep = RegisterUserWithRoles.FindControl("SpecifyRolesStep") as WizardStep;
// Reference the RoleList CheckBoxList
CheckBoxList RoleList = SpecifyRolesStep.FindControl("RoleList") as CheckBoxList;
// Add the checked roles to the just-added user
foreach (ListItem li in RoleList.Items)
{
if (li.Selected)
Roles.AddUserToRole(RegisterUserWithRoles.UserName, li.Text);
}
}
}
ユーザーが "完了" ステップに到達したばかりの場合、イベント ハンドラーは 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 は独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・自分自身 ASP.NET 24時間で2.0です。 Scott は、 または mitchell@4guysfromrolla.com のブログを http://ScottOnWriting.NET介してアクセスできます。
特別な感謝...
このチュートリアル シリーズは、多くの役立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、テレサ マーフィーでした。 今後の MSDN 記事の確認に関心がありますか? もしそうなら、私に行を落としてください mitchell@4GuysFromRolla.com
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示