Sdílet prostřednictvím


Přiřazení rolí uživatelům (C#)

Scott Mitchell

Poznámka

Od napsání tohoto článku se zprostředkovatelé členství ASP.NET nahradili službou ASP.NET Identity. Důrazně doporučujeme aktualizovat aplikace tak, aby používaly platformu ASP.NET Identity Platform místo zprostředkovatelů členství, které se objevovalo v době psaní tohoto článku. ASP.NET Identity má oproti systému členství ASP.NET řadu výhod, mezi které patří:

  • Lepší výkon
  • Vylepšená rozšiřitelnost a testovatelnost
  • Podpora OAuth, OpenID Connect a dvojúrovňového ověřování
  • Podpora identit založených na deklarací identity
  • Lepší interoperabilita s ASP.Net Core

Stažení kódu nebo stažení souboru PDF

V tomto kurzu vytvoříme dvě ASP.NET stránky, které vám pomůžou se správou uživatelů, kteří patří do jakých rolí. První stránka bude obsahovat možnosti, které vám umožní zjistit, kteří uživatelé patří do dané role, do jakých rolí konkrétní uživatel patří, a možnost přiřadit nebo odebrat konkrétního uživatele z určité role. Na druhé stránce rozšíříme ovládací prvek CreateUserWizard tak, aby zahrnoval krok pro určení rolí, do nichž nově vytvořený uživatel patří. To je užitečné ve scénářích, kdy správce může vytvářet nové uživatelské účty.

Úvod

V předchozím kurzu jsme prozkoumali architekturu SqlRoleProviderrolí a ; zjistili jsme, jak pomocí Roles třídy vytvářet, načítat a odstraňovat role. Kromě vytváření a odstraňování rolí potřebujeme mít možnost přiřazovat nebo odebírat uživatele z role. ASP.NET se bohužel nedodává s žádnými webovými ovládacími prvky pro správu uživatelů, kteří patří do jakých rolí. Místo toho musíme vytvořit vlastní ASP.NET stránky pro správu těchto přidružení. Dobrou zprávou je, že přidávání a odebírání uživatelů do rolí je poměrně snadné. Třída Roles obsahuje několik metod pro přidání jednoho nebo více uživatelů do jedné nebo více rolí.

V tomto kurzu vytvoříme dvě ASP.NET stránky, které vám pomůžou se správou uživatelů, kteří patří do jakých rolí. První stránka bude obsahovat možnosti, které vám umožní zjistit, kteří uživatelé patří do dané role, do jakých rolí konkrétní uživatel patří, a možnost přiřadit nebo odebrat konkrétního uživatele z určité role. Na druhé stránce rozšíříme ovládací prvek CreateUserWizard tak, aby zahrnoval krok pro určení rolí, do nichž nově vytvořený uživatel patří. To je užitečné ve scénářích, kdy správce může vytvářet nové uživatelské účty.

Pusťme se do toho.

Výpis uživatelů, kteří patří do jakých rolí

Prvním obchodním pořádekem pro tento kurz je vytvoření webové stránky, ze které lze uživatele přiřazovat k rolím. Než se začneme zabývat tím, jak přiřadit uživatele k rolím, zaměřme se nejprve na to, jak určit, kteří uživatelé patří do jakých rolí. Tyto informace lze zobrazit dvěma způsoby: "podle role" nebo "podle uživatele". Mohli bychom návštěvníkovi povolit, aby vybral roli a pak mu zobrazil všechny uživatele, kteří do role patří (zobrazení podle role), nebo bychom mohli návštěvníka vyzvat, aby vybral uživatele a pak mu zobrazil role přiřazené danému uživateli (zobrazení "podle uživatele").

Zobrazení "podle role" je užitečné v případech, kdy návštěvník chce znát sadu uživatelů, kteří patří do určité role; Zobrazení podle uživatele je ideální, když návštěvník potřebuje znát roli konkrétního uživatele. Pojďme, aby naše stránka obsahovala rozhraní "podle role" i "podle uživatele".

Začneme vytvořením rozhraní "podle uživatele". Toto rozhraní se bude skládat z rozevíracího seznamu a seznamu zaškrtávacích políček. Rozevírací seznam se naplní sadou uživatelů v systému. zaškrtávací políčka zobrazí výčet rolí. Když vyberete uživatele z rozevíracího seznamu, zkontrolujete role, do kterých uživatel patří. Osoba, která stránku navštíví, pak může zaškrtnutím nebo zrušením zaškrtnutí políček přidat nebo odebrat vybraného uživatele z odpovídajících rolí.

Poznámka

Použití rozevíracího seznamu k výpisu uživatelských účtů není ideální volbou pro weby, kde můžou existovat stovky uživatelských účtů. Rozevírací seznam je navržený tak, aby uživatelům umožňoval vybrat jednu položku z relativně krátkého seznamu možností. S rostoucím počtem položek seznamu se rychle stává nepraktným. Pokud vytváříte web, který bude mít potenciálně velký počet uživatelských účtů, můžete zvážit použití alternativního uživatelského rozhraní, jako je stránkovací GridView nebo filtrovatelné rozhraní, které návštěvníka vyzve k výběru dopisu a zobrazí pouze uživatele, jejichž uživatelské jméno začíná vybraným písmenem.

Krok 1: Vytvoření uživatelského rozhraní podle uživatele

UsersAndRoles.aspx Otevřete stránku. Na začátek stránky přidejte ovládací prvek Label Web s názvem ActionStatus a vymažte jeho Text vlastnost. Tento popisek použijeme k poskytnutí zpětné vazby k provedeným akcím, které zobrazí zprávy typu "Uživatel Tito byl přidán do role Administrators" nebo "Uživatel Jisun byl odebrán z role Správci". Aby tyto zprávy vynikly, nastavte vlastnost Popisek CssClass na "Důležité".

<p align="center"> 

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

Dále do šablony stylů přidejte následující definici Styles.css třídy CSS:

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

Tato definice šablon stylů CSS dává prohlížeči pokyn, aby zobrazil popisek pomocí velkého červeného písma. Obrázek 1 znázorňuje tento efekt prostřednictvím Designer sady Visual Studio.

Výsledkem vlastnosti CssClass popisku je velké červené písmo.

Obrázek 1: Výsledkem vlastnosti popisku CssClass je velké červené písmo (kliknutím zobrazíte obrázek v plné velikosti)

Dále na stránku přidejte dropDownList, nastavte jeho ID vlastnost na UserLista nastavte jeho AutoPostBack vlastnost na True. Tento rozevírací seznam použijeme k zobrazení seznamu všech uživatelů v systému. Tento rozevírací seznam bude vázán na kolekci MembershipUser objekty. Protože chceme, aby dropDownList zobrazoval vlastnost UserName objektu MembershipUser (a použít ji jako hodnotu položek seznamu), nastavte vlastnosti a DataValueField DropDownList DataTextField na "UserName".

Pod rozevírací seznam přidejte repeater s názvem UsersRoleList. Tento opakovač zobrazí seznam všech rolí v systému jako řadu zaškrtávacích políček. Definujte opakovač ItemTemplate pomocí následujícího deklarativního kódu:

<asp:Repeater ID="UsersRoleList" runat="server"> 
     <ItemTemplate> 
          <asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true" 

               Text='<%# Container.DataItem %>' /> 
          <br /> 
     </ItemTemplate> 
</asp:Repeater>

Kód ItemTemplate obsahuje jeden ovládací prvek CheckBox Web s názvem RoleCheckBox. Vlastnost CheckBox AutoPostBack je nastavena na True a Text vlastnost je vázána na Container.DataItem. Důvodem syntaxe datové vazby je jednoduše Container.DataItem to, že architektura Roles vrací seznam názvů rolí jako pole řetězců a právě toto pole řetězců vytvoříme vazbu na repeater. Podrobný popis, proč se tato syntaxe používá k zobrazení obsahu pole vázaného na webový ovládací prvek dat, je nad rámec tohoto kurzu. Další informace o této záležitosti najdete v tématu Vytvoření vazby skalárního pole k webovému ovládacímu prvku dat.

V tomto okamžiku by deklarativní kód rozhraní podle uživatele měl vypadat podobně jako následující:

<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>

Teď jsme připraveni napsat kód pro vytvoření vazby sady uživatelských účtů na DropDownList a sady rolí s repeaterem. Do třídy kódu na pozadí stránky přidejte metodu s názvem BindUsersToUserList a další metodu s názvem BindRolesListpomocí následujícího kódu:

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

Metoda BindUsersToUserList načte všechny uživatelské účty v systému prostřednictvím Membership.GetAllUsers metody . Tím se MembershipUserCollection vrátí objekt, což je kolekce MembershipUser instancí. Tato kolekce je pak vázána na UserList DropDownList. InstanceMembershipUser, které kolekci vytyčily, obsahují různé vlastnosti, jako jsou UserName, EmailCreationDate, a IsOnline. Chcete-li dát dropDownList pokyn k zobrazení hodnoty UserName vlastnosti, ujistěte se, že UserList vlastnosti a DataValueField DropDownList DataTextField jsou nastaveny na "UserName".

Poznámka

Metoda Membership.GetAllUsers má dvě přetížení: jedno, které nepřijímá žádné vstupní parametry a vrací všechny uživatele, a druhé, které přijímá celočíselné hodnoty pro index stránky a velikost stránky a vrací pouze zadanou podmnožinu uživatelů. Pokud jsou v prvku uživatelského rozhraní s možností stránky zobrazeny velké množství uživatelských účtů, druhé přetížení lze použít k efektivnějšímu stránkování uživatelů, protože vrací pouze přesnou podmnožinu uživatelských účtů, nikoli všechny.

Metoda BindRolesToList začíná voláním Roles metody třídyGetAllRoles, která vrací pole řetězců obsahující role v systému. Toto pole řetězců je pak vázáno na repeater.

Nakonec musíme tyto dvě metody volat při prvním načtení stránky. Do obslužné rutiny Page_Load události přidejte následující kód:

protected void Page_Load(object sender, EventArgs e) 
{ 
     if (!Page.IsPostBack) 
     { 
          // Bind the users and roles 
          BindUsersToUserList(); 
          BindRolesToList(); 
     } 
}

Po provedení tohoto kódu se chvíli podívejte na stránku prostřednictvím prohlížeče. obrazovka by měla vypadat podobně jako na obrázku 2. V rozevíracím seznamu se vyplní všechny uživatelské účty a pod ním se každá role zobrazí jako zaškrtávací políčko. Vzhledem k tomu, že jsme nastavili AutoPostBack vlastnosti DropDownList a CheckBoxes na True, změna vybraného uživatele nebo zaškrtnutí nebo zrušení zaškrtnutí role způsobí zpětné odeslání. Neprovádí se ale žádná akce, protože jsme ještě nenapsali kód pro zpracování těchto akcí. Tyto úkoly se budeme zabývat v následujících dvou částech.

Na stránce se zobrazují uživatelé a role.

Obrázek 2: Stránka zobrazuje uživatele a role (kliknutím zobrazíte obrázek v plné velikosti).

Kontrola rolí, do nichž vybraný uživatel patří

Když se stránka poprvé načte nebo když návštěvník vybere nového uživatele z rozevíracího seznamu, musíme aktualizovat UsersRoleListzaškrtávací políčka tak, aby byla daná role zaškrtnutá jenom v případě, že vybraný uživatel patří do této role. K tomu vytvořte metodu s názvem CheckRolesForSelectedUser s následujícím kódem:

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

Výše uvedený kód začíná určením, kdo je vybraný uživatel. Pak použije metodu třídyGetRolesForUser(userName) Roles k vrácení zadané sady rolí uživatele jako pole řetězců. Dále se zobrazí výčet položek repeateru a na zaškrtávací políčko každé položky RoleCheckBox se programově odkazuje. Zaškrtávací políčko je zaškrtnuté pouze v případě, že role, které odpovídá, je obsažena selectedUsersRoles v poli řetězců.

Poznámka

Pokud selectedUserRoles.Contains<string>(...) používáte ASP.NET verzi 2.0, syntaxe se nezkompiluje. Metoda Contains<string> je součástí knihovny LINQ, která je novinkou ASP.NET 3.5. Pokud stále používáte ASP.NET verze 2.0, použijte místo toho metoduArray.IndexOf<string> .

Metodu CheckRolesForSelectedUser je potřeba volat ve dvou případech: při prvním načtení stránky a při každé změně vybraného indexu UserList DropDownList. Proto volejte tuto metodu z obslužné Page_Load rutiny události (po volání a BindRolesToListBindUsersToUserList ). Také vytvořte obslužnou rutinu události pro událost DropDownList SelectedIndexChanged a zavolejte tuto metodu odtud.

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

S tímto kódem můžete stránku otestovat v prohlížeči. Vzhledem k tomu, že stránka UsersAndRoles.aspx v současné době nemá možnost přiřazovat uživatele k rolím, žádní uživatelé nemají role. Za chvíli vytvoříme rozhraní pro přiřazování uživatelů k rolím, takže můžete buď přijmout moje slovo, že tento kód funguje, a ověřit, že to uděláte později, nebo můžete uživatele do rolí přidat ručně vložením záznamů do aspnet_UsersInRoles tabulky, abyste mohli tuto funkci otestovat.

Přiřazování a odebírání uživatelů z rolí

Když návštěvník zkontroluje nebo zruší zaškrtnutí políčka v repeateru UsersRoleList , musíme přidat nebo odebrat vybraného uživatele z odpovídající role. Vlastnost CheckBox AutoPostBack je aktuálně nastavena na True, což způsobí postback kdykoli CheckBox v Repeateru je zaškrtnuté nebo nezaškrtnuté. Stručně řečeno, potřebujeme vytvořit obslužnou rutinu události pro událost CheckBox CheckChanged . Vzhledem k tomu, že CheckBox je v ovládacím prvku Repeater, musíme ručně přidat obslužnou rutinu události. Začněte tím, že do třídy kódu na pozadí přidáte obslužnou rutinu události jako metodu protected , například takto:

protected void RoleCheckBox_CheckChanged(object sender, EventArgs e) 
{ 

}

Za chvíli se vrátíme a napíšeme kód pro tuto obslužnou rutinu události. Nejdřív ale dokončíme zpracování instalatérských prací. Ze zaškrtávacího políčka v opakovači ItemTemplatepřidejte OnCheckedChanged="RoleCheckBox_CheckChanged". Tato syntaxe prodá obslužnou RoleCheckBox_CheckChanged rutinu události s RoleCheckBoxudálostí CheckedChanged .

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

Naším posledním úkolem je dokončit obslužnou rutinu RoleCheckBox_CheckChanged události. Musíme začít odkazem na ovládací prvek CheckBox, který vyvolal událost, protože tato instance CheckBox nám říká, jaká role byla zaškrtnutá nebo nezaškrtnutá prostřednictvím vlastností Text a Checked . Pomocí těchto informací spolu s uživatelským názvem vybraného uživatele přidáme nebo odebereme uživatele z role prostřednictvím Roles třídy AddUserToRole nebo RemoveUserFromRole metody.

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

     } 
}

Výše uvedený kód začíná programovým odkazem na CheckBox, který vyvolal událost, která je k dispozici prostřednictvím vstupního parametru sender . Pokud je políčko zaškrtnuté, vybraný uživatel se přidá do zadané role, jinak se z role odebere. V obou případech popisek ActionStatus zobrazí zprávu se souhrnem právě provedené akce.

Chvíli si tuto stránku otestujte v prohlížeči. Vyberte uživatele Tito a pak přidejte Titoa k rolím Administrators a Supervisors.

Tito byl přidán do rolí Administrators a Supervisors

Obrázek 3: Tito byl přidán do rolí Administrators a Supervisors (Kliknutím zobrazíte obrázek v plné velikosti)

Dále v rozevíracím seznamu vyberte uživatele Bruce. K dispozici je postback a zaškrtávací políčka repeateru se aktualizují CheckRolesForSelectedUserprostřednictvím . Vzhledem k tomu, že Bruce ještě nepatří do žádné role, nejsou tato dvě políčka zaškrtnutá. V dalším kroku přidejte Bruce do role Supervisors (Správci).

Bruce byl přidán do role Supervisors

Obrázek 4: Bruce byl přidán do role Supervisors (Kliknutím zobrazíte obrázek v plné velikosti)

Pokud chcete dále ověřit funkčnost CheckRolesForSelectedUser metody, vyberte jiného uživatele než Tito nebo Bruce. Všimněte si, že zaškrtávací políčka jsou automaticky nezaškrtnutá a znamená to, že nepatří do žádné role. Vraťte se k Titovi. Zaškrtávací políčka Administrators i Supervisors by měla být zaškrtnutá.

Krok 2: Vytvoření uživatelského rozhraní "Podle rolí"

V tomto okamžiku jsme dokončili rozhraní "podle uživatelů" a jsme připraveni začít řešit rozhraní "podle rolí". Rozhraní "podle rolí" vyzve uživatele k výběru role z rozevíracího seznamu a poté zobrazí sadu uživatelů, kteří patří do této role v objektu GridView.

Přidejte na UsersAndRoles.aspx stránku další ovládací prvek DropDownList. Umístěte ho pod ovládací prvek Repeater, pojmenujte ho RoleLista nastavte jeho AutoPostBack vlastnost na True. Pod něj přidejte Objekt GridView a pojmenujte ho RolesUserList. Tento objekt GridView zobrazí seznam uživatelů, kteří patří do vybrané role. Nastavte vlastnost GridView AutoGenerateColumns na False, přidejte TemplateField do kolekce mřížky Columns a nastavte jeho HeaderText vlastnost na "Users". Definujte pole TemplateField ItemTemplate tak, aby zobrazovala hodnotu výrazu Container.DataItem datové vazby ve Text vlastnosti Label s názvem UserNameLabel.

Po přidání a konfiguraci GridView by měl deklarativní kód rozhraní "by role" vypadat podobně jako následující:

<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>

Musíme naplnit RoleList rozevírací seznam sadou rolí v systému. Chcete-li toho dosáhnout, aktualizujte metodu BindRolesToList tak, aby byla vázána pole řetězců vrácené metodou Roles.GetAllRoles na RolesList DropDownList (stejně jako UsersRoleList Repeater).

private void BindRolesToList() 
{ 
     // Get all of the roles 

     string[] roles = Roles.GetAllRoles(); 
     UsersRoleList.DataSource = roles; 
     UsersRoleList.DataBind(); 

     RoleList.DataSource = roles; 
     RoleList.DataBind(); 
}

Poslední dva řádky v BindRolesToList metodě byly přidány pro vytvoření vazby sady rolí k ovládacímu prvku RoleList DropDownList. Obrázek 5 ukazuje konečný výsledek při prohlížení v prohlížeči – rozevírací seznam naplněný rolemi systému.

Role se zobrazují v rozevíracím seznamu rolí

Obrázek 5: Role se zobrazují v rozevíracím RoleList seznamu (kliknutím zobrazíte obrázek v plné velikosti)

Zobrazení uživatelů, kteří patří do vybrané role

Při prvním načtení stránky nebo při výběru nové role z rozevíracího RoleList seznamu musíme zobrazit seznam uživatelů, kteří patří do této role v GridView. Pomocí následujícího kódu vytvořte metodu s názvem 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(); 
}

Tato metoda začíná získáním vybrané role z rozevíracího RoleList seznamu. Pak použije metoduRoles.GetUsersInRole(roleName) k načtení pole řetězců uživatelských jmen uživatelů, kteří patří do této role. Toto pole je poté vázáno na RolesUserList GridView.

Tuto metodu je třeba volat ve dvou případech: při počátečním načtení stránky a při změně vybrané role v rozevíracím RoleList seznamu. Proto aktualizujte obslužnou rutinu Page_Load události tak, aby se tato metoda vyvolala po volání .CheckRolesForSelectedUser Dále vytvořte obslužnou rutinu RoleListSelectedIndexChanged události pro událost a zavolejte tuto metodu také odtud.

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

S tímto kódem by RolesUserList gridView měl zobrazit uživatele, kteří patří do vybrané role. Jak ukazuje obrázek 6, role Supervisors se skládá ze dvou členů: Bruce a Tito.

GridView zobrazí seznam uživatelů, kteří patří do vybrané role.

Obrázek 6: GridView obsahuje seznam uživatelů, kteří patří do vybrané role (kliknutím zobrazíte obrázek v plné velikosti).

Odebrání uživatelů z vybrané role

Pojďme objekt GridView rozšířit RolesUserList tak, aby obsahoval sloupec tlačítek Odebrat. Kliknutím na tlačítko Odebrat konkrétního uživatele odeberete uživatele z této role.

Začněte tím, že do ovládacího prvku GridView přidáte pole tlačítka Odstranit. Nastavte, aby se toto pole zobrazovalo jako nejvíce vlevo a změňte jeho DeleteText vlastnost z "Odstranit" (výchozí) na "Odebrat".

Snímek obrazovky, který ukazuje, jak přidat tlačítko Odebrat v okně Pole

Obrázek 7: Přidání tlačítka Odebrat do GridView (kliknutím zobrazíte obrázek v plné velikosti)

Po kliknutí na tlačítko "Remove" následuje postback a GridView je RowDeleting vyvolána událost. Pro tuto událost potřebujeme vytvořit obslužnou rutinu události a napsat kód, který uživatele odebere z vybrané role. Vytvořte obslužnou rutinu události a pak přidejte následující kód:

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

Kód začíná určením názvu vybrané role. Potom programově odkazuje na UserNameLabel ovládací prvek z řádku, jehož tlačítko Odebrat bylo kliknuto, aby bylo určeno uživatelské jméno uživatele, který se má odebrat. Uživatel se pak odebere z role voláním Roles.RemoveUserFromRole metody . Objekt RolesUserList GridView se pak aktualizuje a prostřednictvím ActionStatus ovládacího prvku Popisek se zobrazí zpráva.

Poznámka

Tlačítko Odebrat nevyžaduje žádné potvrzení od uživatele před odebráním uživatele z role. Vyzývám vás, abyste přidali určitou úroveň potvrzení uživatele. Jedním z nejjednodušších způsobů, jak akci potvrdit, je dialogové okno potvrzení na straně klienta. Další informace o této technice najdete v tématu Přidání Client-Side potvrzení při odstraňování.

Obrázek 8 znázorňuje stránku po odebrání uživatele Tito ze skupiny Supervisors.

Tito už bohužel není správcem.

Obrázek 8: Tito už bohužel není správcem (kliknutím zobrazíte obrázek v plné velikosti)

Přidání nových uživatelů do vybrané role

Kromě odebrání uživatelů z vybrané role by návštěvník této stránky měl mít také možnost přidat uživatele do vybrané role. Nejlepší rozhraní pro přidání uživatele do vybrané role závisí na počtu uživatelských účtů, které očekáváte. Pokud váš web bude mít jen několik desítek uživatelských účtů nebo méně, můžete použít dropDownList zde. Pokud můžou existovat tisíce uživatelských účtů, měli byste zahrnout uživatelské rozhraní, které umožní návštěvníkovi procházet účty, hledat konkrétní účet nebo filtrovat uživatelské účty jiným způsobem.

Pro tuto stránku použijeme velmi jednoduché rozhraní, které funguje bez ohledu na počet uživatelských účtů v systému. Konkrétně použijeme Textové pole, které návštěvníka vyzve k zadání uživatelského jména uživatele, kterého chce přidat k vybrané roli. Pokud žádný uživatel s tímto jménem neexistuje nebo pokud už je členem role, zobrazíme v ActionStatus poli Popisek zprávu. Pokud ale uživatel existuje a není členem této role, přidáme ho do role a aktualizujeme mřížku.

Přidejte TextBox a Button pod GridView. Nastavte TextBox ID na UserNameToAddToRole a vlastnosti a Text tlačítka ID nastavte na AddUserToRoleButton a "Add User to Role" (Přidat uživatele do role).

<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>

Dále vytvořte obslužnou rutinu ClickAddUserToRoleButton události pro a přidejte následující kód:

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

Většina kódu v obslužné rutině Click události provádí různé ověřovací kontroly. Zajišťuje, že návštěvník zadal uživatelské jméno do Textového UserNameToAddToRole pole, že uživatel existuje v systému a že ještě nepatří do vybrané role. Pokud se některá z těchto kontrol nezdaří, zobrazí se příslušná zpráva a ActionStatus obslužná rutina události se ukončí. Pokud všechny kontroly proběhnou úspěšně, uživatel se přidá do role prostřednictvím Roles.AddUserToRole metody . Potom je vlastnost TextBox Text vymazána, GridView je aktualizována a ActionStatus Label zobrazí zprávu s oznámením, že zadaný uživatel byl úspěšně přidán do vybrané role.

Poznámka

Abychom zajistili, že zadaný uživatel ještě nepatří do vybrané role, používáme metoduRoles.IsUserInRole(userName, roleName) , která vrací logickou hodnotu určující, jestli je uživatel userName členem roleName. Tuto metodu použijeme znovu v dalším kurzu , když se podíváme na autorizaci na základě rolí.

Přejděte na stránku v prohlížeči a v rozevíracím seznamu vyberte roli Supervisors (Správci RoleList ). Zkuste zadat neplatné uživatelské jméno – měla by se zobrazit zpráva s vysvětlením, že uživatel v systému neexistuje.

Do role nelze přidat neexistující uživatele

Obrázek 9: Do role nelze přidat neexistující uživatele (kliknutím zobrazíte obrázek v plné velikosti)

Teď zkuste přidat platného uživatele. Pokračujte a znovu přidejte Titoa do role Správce.

Tito je opět nadřízený!

Obrázek 10: Tito je opět nadřízený! (Kliknutím zobrazíte obrázek v plné velikosti.)

Krok 3: Křížová aktualizace rozhraní "Podle uživatele" a "Podle role"

Stránka UsersAndRoles.aspx nabízí dvě různá rozhraní pro správu uživatelů a rolí. V současné době tato dvě rozhraní fungují nezávisle na sobě, takže je možné, že se změna provedená v jednom rozhraní neprojeví okamžitě v druhém rozhraní. Představte si například, že návštěvník stránky vybere roli Supervisors (Správci) z rozevíracího RoleList seznamu, kde jsou jako její členové uveden Bruce a Tito. V dalším kroku návštěvník vybere z rozevíracího UserList seznamu Tito, který zkontroluje zaškrtávací políčka Administrators a Supervisors v repeateru UsersRoleList . Pokud návštěvník zruší zaškrtnutí role Správce z repeateru, Tito se odebere z role Supervisors, ale tato změna se neprojeví v rozhraní "podle role". GridView bude i nadále zobrazovat Tito jako člena role Supervisors.

Abychom to vyřešili, musíme aktualizovat zobrazení GridView vždy, když je role zaškrtnutá nebo nezaškrtnutá v repeateru UsersRoleList . Podobně potřebujeme aktualizovat repeater vždy, když uživatel odebere nebo přidá do role z rozhraní "podle role".

Repeater v rozhraní "podle uživatele" je aktualizován voláním CheckRolesForSelectedUser metody . Rozhraní "podle role" lze upravit v RolesUserList obslužné rutině RowDeleting události GridView a obslužné rutině AddUserToRoleButtonClick události Button. Proto musíme volat metodu CheckRolesForSelectedUser z každé z těchto metod.

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

Podobně gridView v "by role" rozhraní je aktualizován voláním DisplayUsersBelongingToRole metody a "podle uživatele" rozhraní je upravena prostřednictvím obslužné rutiny RoleCheckBox_CheckChanged události. Proto musíme volat metodu DisplayUsersBelongingToRole z této obslužné rutiny události.

protected void RoleCheckBox_CheckChanged(object sender, EventArgs e) 
{ 
     ... Code removed for brevity... 

     // Refresh the "by role" interface 
     DisplayUsersBelongingToRole(); 
}

S těmito drobnými změnami kódu se rozhraní podle uživatele a role správně křížově aktualizují. Pokud to chcete ověřit, přejděte na stránku v prohlížeči a v rozevíracích UserListRoleList náznacích vyberte Tito a Supervisors (Vedoucí). Všimněte si, že při zrušení zaškrtnutí role Správci pro Tito z Repeater v "by user" rozhraní, Tito se automaticky odebere z GridView v rozhraní "podle role". Přidání Titoa zpět do role Supervisors z rozhraní podle role automaticky znovu zkontroluje políčko Supervisors v rozhraní podle uživatele.

Krok 4: Přizpůsobení průvodce CreateUserWizard tak, aby zahrnoval krok "Určení rolí"

V kurzu Vytváření uživatelských účtů jsme viděli, jak pomocí webového ovládacího prvku CreateUserWizard poskytnout rozhraní pro vytvoření nového uživatelského účtu. Ovládací prvek CreateUserWizard lze použít jedním ze dvou způsobů:

  • Jako prostředek pro návštěvníky, aby si na webu vytvořili svůj vlastní uživatelský účet a
  • Jako prostředek pro správce k vytváření nových účtů

V prvním případě použití návštěvník přijde na web a vyplní CreateUserWizard a zadá své údaje, aby se mohl zaregistrovat na webu. Ve druhém případě správce vytvoří nový účet pro jinou osobu.

Když správce vytváří účet pro někoho jiného, může být užitečné povolit správci určit, do jakých rolí nový uživatelský účet patří. V kurzu Ukládánídalších informací o uživateli jsme viděli, jak přizpůsobit Průvodce vytvořením uživatele přidáním dalšího WizardStepsobjektu . Pojďme se podívat na to, jak přidat další krok do Průvodce vytvořením uživatele, abychom mohli zadat role nového uživatele.

CreateUserWizardWithRoles.aspx Otevřete stránku a přidejte ovládací prvek CreateUserWizard s názvem RegisterUserWithRoles. Nastavte vlastnost ovládacího prvku ContinueDestinationPageUrl na ~/Default.aspx. Vzhledem k tomu, že správce bude používat tento ovládací prvek CreateUserWizard k vytvoření nových uživatelských účtů, nastavte vlastnost ovládacího prvku LoginCreatedUser na False. Tato LoginCreatedUser vlastnost určuje, jestli je návštěvník automaticky přihlášen jako právě vytvořený uživatel, a má výchozí hodnotu True. Nastavili jsme ho na False, protože když správce vytvoří nový účet, chceme ho nechat přihlášený jako on sám.

Pak vyberte přidat nebo odebrat WizardSteps... z inteligentní značky CreateUserWizard a přidejte novou WizardStep, která nastaví jeho ID hodnotu na SpecifyRolesStep. SpecifyRolesStep WizardStep Přesuňte ho tak, aby byl po kroku "Registrace nového účtu", ale před krokem "Dokončit". WizardStepTitle Nastavte vlastnost na "Zadat role", jeho StepType vlastnost na Stepa vlastnost AllowReturn na Hodnotu False.

Snímek obrazovky znázorňující vybrané vlastnosti Zadat role v okně Editoru kolekcí kroků průvodce

Obrázek 11: Přidání možnosti Zadat role WizardStep do průvodce createuserwizard (kliknutím zobrazíte obrázek v plné velikosti)

Po této změně by deklarativní kód createuserwizard měl vypadat takto:

<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>

V části Zadejte role WizardSteppřidejte seznam CheckBoxList s názvem RoleList. Tento seznam CheckBoxList zobrazí seznam dostupných rolí a umožní osobě, která stránku navštíví, zkontrolovat, do jakých rolí nově vytvořený uživatel patří.

Zbývají nám dvě úlohy kódování: nejprve musíme naplnit RoleList CheckBoxList rolemi v systému a za druhé musíme přidat vytvořeného uživatele do vybraných rolí, když se uživatel přesune z kroku Zadat role do kroku "Dokončit". Můžeme provést první úlohu v obslužné rutině Page_Load události. Následující kód programově odkazuje RoleList na CheckBox při první návštěvě stránky a sváže s ním role v systému.

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

Výše uvedený kód by měl vypadat povědomě. V kurzu Ukládánídalších informací o uživateli jsme použili dva FindControl příkazy k odkazování na webový ovládací prvek v rámci vlastního WizardStep. Kód, který sváže role s checkBoxList, byl převzat dříve v tomto kurzu.

Abychom mohli provést druhou programovací úlohu, potřebujeme vědět, kdy byl dokončen krok "Zadat role". Vzpomeňte si, že CreateUserWizard má ActiveStepChanged událost, která se aktivuje pokaždé, když návštěvník přejde z jednoho kroku do druhého. Zde můžeme zjistit, jestli uživatel dosáhl kroku "Complete" (Dokončit). Pokud ano, musíme uživatele přidat do vybraných rolí.

Vytvořte obslužnou rutinu ActiveStepChanged události a přidejte následující kód:

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

Pokud uživatel právě dosáhl kroku Dokončeno, obslužná rutina události vytvoří výčet položek RoleList z CheckBoxList a právě vytvořený uživatel je přiřazen k vybraným rolím.

Tuto stránku můžete navštívit v prohlížeči. Prvním krokem v nástroji CreateUserWizard je standardní krok "Registrace nového účtu", který vyzve k zadání uživatelského jména, hesla, e-mailu a dalších klíčů nového uživatele. Zadejte informace pro vytvoření nového uživatele s názvem Wanda.

Vytvoření nového uživatele Wanda

Obrázek 12: Vytvoření nového uživatele S názvem Wanda (kliknutím zobrazíte obrázek v plné velikosti)

Klikněte na tlačítko Vytvořit uživatele. CreateUserWizard interně volá metodu Membership.CreateUser , vytvoří nový uživatelský účet a pak přejde k dalšímu kroku "Zadat role". Tady jsou uvedené systémové role. Zaškrtněte políčko Supervisors (Vedoucí) a klikněte na Next (Další).

Nastavení Wanda jako člena role Supervisors

Obrázek 13: Nastavení Wanda jako člena role Supervisors (kliknutím zobrazíte obrázek v plné velikosti)

Kliknutím na Další dojde k zpětnému odeslání a aktualizuje ActiveStep se na krok "Dokončeno". V obslužné rutině ActiveStepChanged události se nedávno vytvořený uživatelský účet přiřadí k roli Supervisors. Pokud to chcete ověřit, vraťte se na UsersAndRoles.aspx stránku a v rozevíracím RoleList seznamu vyberte Supervisors (Vedoucí). Jak ukazuje obrázek 14, správci se teď skládají ze tří uživatelů: Bruce, Tito a Wanda.

Bruce, Tito a Wanda jsou všichni vedoucí.

Obrázek 14: Bruce, Tito a Wanda jsou všichni vedoucí (kliknutím zobrazíte obrázek v plné velikosti)

Souhrn

Architektura Rolí nabízí metody pro načtení informací o rolích konkrétního uživatele a metody pro určení, kteří uživatelé patří do zadané role. Kromě toho existuje několik metod pro přidání a odebrání jednoho nebo více uživatelů do jedné nebo více rolí. V tomto kurzu jsme se zaměřili pouze na dvě z těchto metod: AddUserToRole a RemoveUserFromRole. Existují další varianty navržené pro přidání více uživatelů do jedné role a přiřazení více rolí jednomu uživateli.

Tento kurz také zahrnoval rozšíření ovládacího prvku CreateUserWizard o zahrnutí objektu WizardStep pro určení nově vytvořených rolí uživatele. Takový krok by mohl správci pomoct zjednodušit proces vytváření uživatelských účtů pro nové uživatele.

V tomto okamžiku jsme viděli, jak vytvářet a odstraňovat role a jak přidávat a odebírat uživatele z rolí. Ještě se ale podíváme na použití autorizace na základě rolí. V následujícím kurzu se podíváme na definování autorizačních pravidel adres URL na základě rolí po rolích a také na to, jak omezit funkčnost na úrovni stránky na základě aktuálně přihlášených rolí uživatele.

Všechno nejlepší na programování!

Další čtení

Další informace o tématech probíraných v tomto kurzu najdete v následujících zdrojích informací:

O autorovi

Scott Mitchell, autor několika knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Scotta můžete zastihnout na adrese mitchell@4guysfromrolla.com nebo prostřednictvím svého blogu na adrese http://ScottOnWriting.NET.

Zvláštní poděkování...

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavní revidující pro tento kurz byla Teresa Murphyová. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi čáru na mitchell@4GuysFromRolla.com