Przypisywanie ról do użytkowników (C#)
Uwaga
Ponieważ ten artykuł został napisany, dostawcy ASP.NET członkostwa zostały zastąpione przez usługę ASP.NET Identity. Zdecydowanie zalecamy aktualizowanie aplikacji w celu korzystania z platformy ASP.NET Identity , a nie dostawców członkostwa opisanych w tym artykule. ASP.NET Identity ma wiele zalet w systemie członkostwa ASP.NET, w tym :
- Lepsza wydajność
- Ulepszona rozszerzalność i możliwość testowania
- Obsługa uwierzytelniania OAuth, OpenID Connect i uwierzytelniania dwuskładnikowego
- Obsługa tożsamości opartej na oświadczeniach
- Lepsza współdziałanie z platformą ASP.Net Core
Pobierz kod lub pobierz plik PDF
W tym samouczku utworzymy dwie strony ASP.NET, które ułatwiają zarządzanie użytkownikami należącymi do ról. Pierwsza strona będzie zawierać obiekty, aby zobaczyć, którzy użytkownicy należą do danej roli, do jakich ról należy określony użytkownik, oraz możliwość przypisywania lub usuwania określonego użytkownika z określonej roli. Na drugiej stronie rozszerzymy kontrolkę CreateUserWizard, tak aby zawierała krok określający, do jakich ról należy nowo utworzony użytkownik. Jest to przydatne w scenariuszach, w których administrator może tworzyć nowe konta użytkowników.
Wprowadzenie
W poprzednim samouczku przeanalizowano platformę Role i SqlRoleProvider
element ; zobaczyliśmy, jak używać Roles
klasy do tworzenia, pobierania i usuwania ról. Oprócz tworzenia i usuwania ról musimy mieć możliwość przypisywania lub usuwania użytkowników z roli. Niestety, ASP.NET nie jest dostarczana z żadnymi kontrolkami sieci Web do zarządzania użytkownikami należącymi do ról. Zamiast tego musimy utworzyć własne strony ASP.NET w celu zarządzania tymi skojarzeniami. Dobrą wiadomością jest to, że dodawanie i usuwanie użytkowników do ról jest dość proste. Klasa Roles
zawiera wiele metod dodawania co najmniej jednego użytkownika do co najmniej jednej roli.
W tym samouczku utworzymy dwie strony ASP.NET, które ułatwiają zarządzanie użytkownikami należącymi do ról. Pierwsza strona będzie zawierać obiekty, aby zobaczyć, którzy użytkownicy należą do danej roli, do jakich ról należy określony użytkownik, oraz możliwość przypisywania lub usuwania określonego użytkownika z określonej roli. Na drugiej stronie rozszerzymy kontrolkę CreateUserWizard, tak aby zawierała krok określający, do jakich ról należy nowo utworzony użytkownik. Jest to przydatne w scenariuszach, w których administrator może tworzyć nowe konta użytkowników.
Zaczynamy!
Wyświetlanie listy użytkowników należących do ról
Pierwsza kolejność działalności biznesowej dla tego samouczka polega na utworzeniu strony internetowej, z której użytkownicy mogą być przypisywani do ról. Zanim zaczniemy się martwić o sposób przypisywania użytkowników do ról, najpierw skoncentrujmy się na tym, jak określić, do jakich ról należą użytkownicy. Istnieją dwa sposoby wyświetlania tych informacji: "według roli" lub "według użytkownika". Możemy zezwolić odwiedzającym na wybranie roli, a następnie pokazać im wszystkich użytkowników należących do roli (wyświetlanie "według roli") lub poprosić odwiedzających o wybranie użytkownika, a następnie wyświetlenie im ról przypisanych do tego użytkownika (wyświetlanie "według użytkownika").
Widok "według roli" jest przydatny w sytuacjach, gdy odwiedzający chce znać zestaw użytkowników należących do określonej roli; widok "według użytkownika" jest idealny, gdy użytkownik musi znać role określonego użytkownika. Na naszej stronie znajdują się zarówno interfejsy "by role" i "by user".
Zaczniemy od utworzenia interfejsu "by user". Ten interfejs będzie składać się z listy rozwijanej i listy pól wyboru. Lista rozwijana zostanie wypełniona zestawem użytkowników w systemie; pola wyboru będą wyliczać role. Wybranie użytkownika z listy rozwijanej spowoduje sprawdzenie tych ról, do których należy użytkownik. Osoba odwiedzająca stronę może następnie zaznaczyć lub usunąć zaznaczenie pól wyboru, aby dodać lub usunąć wybranego użytkownika z odpowiednich ról.
Uwaga
Używanie listy rozwijanej do wyświetlania listy kont użytkowników nie jest idealnym wyborem dla witryn internetowych, w których mogą istnieć setki kont użytkowników. Lista rozwijana została zaprojektowana tak, aby umożliwić użytkownikowi wybranie jednego elementu z stosunkowo krótkiej listy opcji. Szybko staje się niewygodny w miarę wzrostu liczby elementów listy. Jeśli tworzysz witrynę internetową, która będzie mieć potencjalnie dużą liczbę kont użytkowników, warto rozważyć użycie alternatywnego interfejsu użytkownika, takiego jak stronicowy element GridView lub interfejs z możliwością filtrowania, który wyświetla monit o wybranie litery przez odwiedzających, a następnie pokazuje tylko tych użytkowników, których nazwa użytkownika zaczyna się od wybranej litery.
Krok 1. Kompilowanie interfejsu użytkownika "Według użytkownika"
UsersAndRoles.aspx
Otwórz stronę. W górnej części strony dodaj kontrolkę Etykieta sieci Web o nazwie ActionStatus
i wyczyść jej Text
właściwość. Użyjemy tej etykiety, aby przekazać opinię na temat wykonanych akcji, wyświetlając komunikaty takie jak "Użytkownik Tito został dodany do roli Administratorzy" lub "Użytkownik Jisun został usunięty z roli Nadzorcy". Aby wyróżnić te komunikaty, ustaw właściwość Etykieta CssClass
na "Ważne".
<p align="center">
<asp:Label ID="ActionStatus" runat="server" CssClass="Important"></asp:Label>
</p>
Następnie dodaj następującą definicję klasy CSS do Styles.css
arkusza stylów:
.Important
{
font-size: large;
color: Red;
}
Ta definicja CSS instruuje przeglądarkę, aby wyświetlała etykietę przy użyciu dużej, czerwonej czcionki. Rysunek 1 przedstawia ten efekt za pośrednictwem programu Visual Studio Projektant.
Rysunek 1. Właściwość etykiety CssClass
powoduje wyświetlenie dużej, czerwonej czcionki (kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie dodaj listę DropDownList do strony, ustaw jej ID
właściwość na , i ustaw jej AutoPostBack
właściwość na UserList
True. Użyjemy tej listy rozwijanej, aby wyświetlić listę wszystkich użytkowników w systemie. Ta lista rozwijana zostanie powiązana z kolekcją obiektów MembershipUser. Ponieważ chcemy, aby lista Rozwijana Lista rozwijana wyświetlała właściwość UserName obiektu MembershipUser (i użyjemy jej jako wartości elementów listy), ustaw właściwości Listy rozwijanej DataTextField
na DataValueField
"UserName".
Poniżej listy rozwijanej dodaj element Repeater o nazwie UsersRoleList
. To repeater wyświetli listę wszystkich ról w systemie jako serię pól wyboru. Zdefiniuj element Repeater ItemTemplate
przy użyciu następującego deklaratywnego znaczników:
<asp:Repeater ID="UsersRoleList" runat="server">
<ItemTemplate>
<asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true"
Text='<%# Container.DataItem %>' />
<br />
</ItemTemplate>
</asp:Repeater>
Znaczniki ItemTemplate
zawierają pojedynczą kontrolkę sieci Web CheckBox o nazwie RoleCheckBox
. Właściwość CheckBox jest ustawiona AutoPostBack
na wartość True, a Text
właściwość jest powiązana z Container.DataItem
wartością . Powodem, dla którego składnia powiązania danych jest po prostu Container.DataItem
taka, że struktura Role zwraca listę nazw ról jako tablicę ciągów i jest to tablica ciągów, którą będziemy wiązać z repeaterem. Dokładny opis przyczyny użycia tej składni do wyświetlania zawartości tablicy powiązanej z kontrolką sieci Web danych wykracza poza zakres tego samouczka. Aby uzyskać więcej informacji na ten temat, zobacz Powiązanie tablicy skalarnej z kontrolką sieci Web danych.
W tym momencie znacznik deklaratywny interfejsu użytkownika powinien wyglądać podobnie do następującego:
<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>
Teraz możemy napisać kod, aby powiązać zestaw kont użytkowników z listą rozwijaną i zestawem ról na repeater. W klasie code-behind strony dodaj metodę o nazwie i inną o nazwie BindUsersToUserList
BindRolesList
, używając następującego kodu:
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
pobiera wszystkie konta użytkowników w systemie za pośrednictwem Membership.GetAllUsers
metody . MembershipUserCollection
Zwraca obiekt, który jest kolekcją MembershipUser
wystąpień. Ta kolekcja jest następnie powiązana z listą UserList
Rozwijaną. MembershipUser
Wystąpienia, które makijaż kolekcji zawierają różne właściwości, takie jak UserName
, Email
, CreationDate
i IsOnline
. Aby poinstruować listę DropDownList, aby wyświetlić wartość UserName
właściwości, upewnij się, że UserList
właściwości listy rozwijanej DataTextField
i DataValueField
właściwości zostały ustawione na "UserName".
Uwaga
Metoda Membership.GetAllUsers
ma dwa przeciążenia: jeden, który nie akceptuje parametrów wejściowych i zwraca wszystkich użytkowników, oraz jeden, który przyjmuje wartości całkowite dla indeksu strony i rozmiar strony, i zwraca tylko określony podzbiór użytkowników. Jeśli w elemecie interfejsu użytkownika jest wyświetlana duża liczba kont użytkowników, drugie przeciążenie może służyć do bardziej wydajnej strony za pośrednictwem użytkowników, ponieważ zwraca tylko dokładny podzbiór kont użytkowników, a nie wszystkich z nich.
Metoda BindRolesToList
rozpoczyna się od wywołania Roles
metody klasyGetAllRoles
, która zwraca tablicę ciągów zawierającą role w systemie. Ta tablica ciągów jest następnie powiązana z repeaterem.
Na koniec musimy wywołać te dwie metody po pierwszym załadowaniu strony. Dodaj następujący kod do programu obsługi zdarzeń Page_Load
:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Bind the users and roles
BindUsersToUserList();
BindRolesToList();
}
}
Po utworzeniu tego kodu poświęć chwilę, aby odwiedzić stronę za pośrednictwem przeglądarki; Ekran powinien wyglądać podobnie do rysunku 2. Wszystkie konta użytkowników są wypełniane na liście rozwijanej i poniżej tej roli są wyświetlane jako pole wyboru. Ponieważ ustawiamy AutoPostBack
właściwości Listy rozwijanej i Pola wyboru na True, zmiana wybranego użytkownika lub sprawdzanie lub usuwanie zaznaczenia roli powoduje powrót. Nie jest jednak wykonywana żadna akcja, ponieważ musimy jeszcze napisać kod do obsługi tych akcji. W kolejnych dwóch sekcjach zajmiemy się tymi zadaniami.
Rysunek 2. Strona wyświetla użytkowników i role (kliknij, aby wyświetlić obraz pełnowymiarowy)
Sprawdzanie ról, do których należy wybrany użytkownik
Gdy strona zostanie załadowana po raz pierwszy lub gdy odwiedzający wybierze nowego użytkownika z listy rozwijanej, musimy zaktualizować UsersRoleList
pola wyboru , aby pole wyboru danej roli było zaznaczone tylko wtedy, gdy wybrany użytkownik należy do tej roli. Aby to zrobić, utwórz metodę o nazwie CheckRolesForSelectedUser
z następującym kodem:
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;
}
}
Powyższy kod rozpoczyna się od określenia, kim jest wybrany użytkownik. Następnie używa metody klasy GetRolesForUser(userName)
Roles, aby zwrócić zestaw ról określonego użytkownika jako tablicę ciągów. Następnie elementy repeatera są wyliczane, a pole wyboru każdego elementu RoleCheckBox
jest programowo przywoływane. Pole wyboru jest sprawdzane tylko wtedy, gdy rola, z jaką odpowiada, znajduje się w tablicy ciągów selectedUsersRoles
.
Uwaga
Składnia selectedUserRoles.Contains<string>(...)
nie zostanie skompilowana, jeśli używasz ASP.NET wersji 2.0. Metoda Contains<string>
jest częścią biblioteki LINQ, która jest nowa do ASP.NET 3.5. Jeśli nadal używasz ASP.NET w wersji 2.0, użyj Array.IndexOf<string>
metody .
Metoda CheckRolesForSelectedUser
musi być wywoływana w dwóch przypadkach: po pierwszym załadowaniu strony i za każdym razem, gdy UserList
wybrany indeks Listy rozwijanej zostanie zmieniony. W związku z tym wywołaj tę metodę z Page_Load
procedury obsługi zdarzeń (po wywołaniach do BindUsersToUserList
i BindRolesToList
). Ponadto utwórz procedurę obsługi zdarzeń dla zdarzenia DropDownList SelectedIndexChanged
i wywołaj tę metodę stamtąd.
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();
}
Za pomocą tego kodu możesz przetestować stronę za pośrednictwem przeglądarki. Jednak ponieważ UsersAndRoles.aspx
strona obecnie nie ma możliwości przypisywania użytkowników do ról, żaden użytkownik nie ma ról. Utworzymy interfejs do przypisywania użytkowników do ról za chwilę, więc możesz użyć mojego słowa, że ten kod działa i sprawdzi, czy to zrobi później, lub możesz ręcznie dodać użytkowników do ról, wstawiając rekordy do aspnet_UsersInRoles
tabeli w celu przetestowania tej funkcji teraz.
Przypisywanie i usuwanie użytkowników z ról
Gdy odwiedzający sprawdza lub usuwa zaznaczenie pola wyboru w UsersRoleList
repeaterze, musimy dodać lub usunąć wybranego użytkownika z odpowiedniej roli. Właściwość CheckBox AutoPostBack
jest obecnie ustawiona na true, co powoduje, że po powrocie zwrotne w dowolnym momencie pole wyboru w repeaterze jest zaznaczone lub niezaznaczone. Krótko mówiąc, musimy utworzyć procedurę obsługi zdarzeń dla zdarzenia CheckBox CheckChanged
. Ponieważ Pole wyboru znajduje się w kontrolce Repeater, musimy ręcznie dodać instalację kanalizającą programu obsługi zdarzeń. Zacznij od dodania procedury obsługi zdarzeń do klasy kod-behind jako protected
metody, w następujący sposób:
protected void RoleCheckBox_CheckChanged(object sender, EventArgs e)
{
}
Wrócimy do pisania kodu dla tej procedury obsługi zdarzeń w ciągu chwili. Najpierw ukończmy obsługę instalacji hydraulicznej. W polu CheckBox w elemencie Repeater ItemTemplate
dodaj OnCheckedChanged="RoleCheckBox_CheckChanged"
element . Ta składnia podłącza procedurę RoleCheckBox_CheckChanged
obsługi zdarzeń do RoleCheckBox
zdarzenia .s CheckedChanged
.
<asp:CheckBox runat="server" ID="RoleCheckBox"
AutoPostBack="true"
Text='<%# Container.DataItem %>'
OnCheckedChanged="RoleCheckBox_CheckChanged" />
Naszym ostatnim zadaniem jest ukończenie procedury obsługi zdarzeń RoleCheckBox_CheckChanged
. Musimy zacząć od odwoływania się do kontrolki CheckBox, która wywołała zdarzenie, ponieważ to wystąpienie CheckBox informuje nas, jaka rola została sprawdzona lub niezaznaczone za pośrednictwem jej Text
właściwości i Checked
. Korzystając z tych informacji wraz z userName wybranego użytkownika, dodajemy lub usuwamy użytkownika z roli za pośrednictwem Roles
klasy AddUserToRole
lub 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);
}
}
Powyższy kod rozpoczyna się od programowego odwoływania się do kontrolki CheckBox, która wywołała zdarzenie, które jest dostępne za pośrednictwem parametru wejściowego sender
. Jeśli pole wyboru jest zaznaczone, wybrany użytkownik zostanie dodany do określonej roli, w przeciwnym razie zostaną one usunięte z roli. W obu przypadkach etykieta ActionStatus
wyświetla komunikat podsumowujący właśnie wykonaną akcję.
Poświęć chwilę, aby przetestować tę stronę za pośrednictwem przeglądarki. Wybierz użytkownika Tito, a następnie dodaj Tito do ról Administratorzy i Nadzorcy.
Rysunek 3. Tito został dodany do ról administratorów i nadzorców (kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie wybierz użytkownika Bruce'a z listy rozwijanej. Istnieje postback, a pola CheckBoxes repeatera są aktualizowane za pośrednictwem elementu CheckRolesForSelectedUser
. Ponieważ Bruce nie należy jeszcze do żadnych ról, dwa pola wyboru są niezaznaczone. Następnie dodaj Bruce'a do roli Nadzorcy.
Rysunek 4. Bruce został dodany do roli nadzorców (kliknij, aby wyświetlić obraz pełnowymiarowy)
Aby dokładniej sprawdzić funkcjonalność CheckRolesForSelectedUser
metody, wybierz użytkownika innego niż Tito lub Bruce. Zwróć uwagę, że pola wyboru są automatycznie niezaznaczone, co oznacza, że nie należą do żadnych ról. Wróć do Tito. Należy zaznaczyć pola wyboru Administratorzy i Nadzorcy.
Krok 2. Kompilowanie interfejsu użytkownika "Według ról"
W tym momencie ukończyliśmy interfejs "by users" i jesteśmy gotowi do rozpoczęcia walki z interfejsem "według ról". Interfejs "według ról" monituje użytkownika o wybranie roli z listy rozwijanej, a następnie wyświetla zestaw użytkowników należących do tej roli w siatce.
Dodaj kolejną kontrolkę UsersAndRoles.aspx
DropDownList do strony. Umieść ten element pod kontrolką Repeater, nadaj jej RoleList
nazwę i ustaw jej AutoPostBack
właściwość na true. Poniżej tego dodaj element GridView i nadaj mu nazwę RolesUserList
. Ten element GridView wyświetli listę użytkowników należących do wybranej roli. Ustaw właściwość GridView AutoGenerateColumns
na wartość False, dodaj wartość TemplateField do kolekcji siatki Columns
i ustaw jej HeaderText
właściwość na "Użytkownicy". Zdefiniuj pole szablonu ItemTemplate
tak, aby wyświetlało wartość wyrażenia Container.DataItem
powiązania danych we Text
właściwości Etykiety o nazwie UserNameLabel
.
Po dodaniu i skonfigurowaniu kontrolki GridView znacznik deklaratywny interfejsu "by role" powinien wyglądać podobnie do następującego:
<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>
Musimy wypełnić Listę RoleList
rozwijaną zestawem ról w systemie. Aby to osiągnąć, zaktualizuj metodę BindRolesToList
tak, aby wiązała tablicę ciągów zwróconą przez Roles.GetAllRoles
metodę do RolesList
listy DropDownList (a także UsersRoleList
repeater).
private void BindRolesToList()
{
// Get all of the roles
string[] roles = Roles.GetAllRoles();
UsersRoleList.DataSource = roles;
UsersRoleList.DataBind();
RoleList.DataSource = roles;
RoleList.DataBind();
}
Dodano dwa ostatnie wiersze metody w BindRolesToList
celu powiązania zestawu ról z kontrolką RoleList
DropDownList. Rysunek 5 przedstawia wynik końcowy wyświetlany za pośrednictwem przeglądarki — listę rozwijaną wypełnioną rolami systemu.
Rysunek 5. Role są wyświetlane na liście rozwijanej RoleList
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Wyświetlanie użytkowników należących do wybranej roli
Po pierwszym załadowaniu strony lub wybraniu RoleList
nowej roli z listy rozwijanej musimy wyświetlić listę użytkowników należących do tej roli w elemecie GridView. Utwórz metodę o nazwie DisplayUsersBelongingToRole
przy użyciu następującego kodu:
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();
}
Ta metoda rozpoczyna się od pobrania wybranej roli z listy rozwijanej RoleList
. Następnie używa Roles.GetUsersInRole(roleName)
metody , aby pobrać tablicę ciągów userNames użytkowników należących do tej roli. Ta tablica jest następnie powiązana z elementem RolesUserList
GridView.
Ta metoda musi być wywoływana w dwóch okolicznościach: gdy strona zostanie początkowo załadowana, a wybrana rola w liście rozwijanej RoleList
zmieni się. W związku z tym zaktualizuj procedurę Page_Load
obsługi zdarzeń tak, aby ta metoda jest wywoływana po wywołaniu metody .CheckRolesForSelectedUser
Następnie utwórz procedurę obsługi zdarzeń dla RoleList
zdarzenia i SelectedIndexChanged
wywołaj tę metodę.
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();
}
W tym kodzie element RolesUserList
GridView powinien wyświetlać tych użytkowników, którzy należą do wybranej roli. Jak pokazano na rysunku 6, rola Nadzorcy składa się z dwóch członków: Bruce'a i Tito.
Rysunek 6. Widok GridView wyświetla listę użytkowników należących do wybranej roli (kliknij, aby wyświetlić obraz pełnowymiarowy)
Usuwanie użytkowników z wybranej roli
Rozszerzmy element GridView, RolesUserList
aby zawierał kolumnę przycisków "Usuń". Kliknięcie przycisku "Usuń" dla określonego użytkownika spowoduje usunięcie ich z tej roli.
Zacznij od dodania pola przycisku Usuń do kontrolki GridView. Ustaw to pole jako najbardziej złożone po lewej stronie i zmień jego DeleteText
właściwość z "Usuń" (wartość domyślna) na "Usuń".
Rysunek 7. Dodawanie przycisku "Usuń" do widoku GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po kliknięciu przycisku "Usuń" zostanie wyświetlony komunikat zwrotny, a zdarzenie GridView RowDeleting
zostanie podniesione. Musimy utworzyć procedurę obsługi zdarzeń dla tego zdarzenia i napisać kod, który usuwa użytkownika z wybranej roli. Utwórz procedurę obsługi zdarzeń, a następnie dodaj następujący kod:
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);
}
Kod rozpoczyna się od określenia wybranej nazwy roli. Następnie programowo odwołuje się do UserNameLabel
kontrolki z wiersza, którego przycisk "Usuń" został kliknięty w celu określenia userName użytkownika do usunięcia. Użytkownik zostanie następnie usunięty z roli za pomocą wywołania metody Roles.RemoveUserFromRole
. Element RolesUserList
GridView jest następnie odświeżany, a komunikat jest wyświetlany za pośrednictwem kontrolki ActionStatus
Etykieta.
Uwaga
Przycisk "Usuń" nie wymaga żadnego potwierdzenia od użytkownika przed usunięciem użytkownika z roli. Zapraszam do dodania pewnego poziomu potwierdzenia użytkownika. Jednym z najprostszych sposobów potwierdzenia akcji jest okno dialogowe potwierdzania po stronie klienta. Aby uzyskać więcej informacji na temat tej techniki, zobacz Dodawanie Client-Side potwierdzenia podczas usuwania.
Rysunek 8 przedstawia stronę po usunięciu użytkownika Tito z grupy Nadzorcy.
Rysunek 8. Niestety, Tito nie jest już nadzorcą (kliknij, aby wyświetlić obraz pełnowymiarowy)
Dodawanie nowych użytkowników do wybranej roli
Oprócz usuwania użytkowników z wybranej roli odwiedzający tę stronę powinien również mieć możliwość dodania użytkownika do wybranej roli. Najlepszy interfejs dodawania użytkownika do wybranej roli zależy od liczby oczekiwanych kont użytkowników. Jeśli witryna internetowa będzie zawierać tylko kilka tuzinów kont użytkowników lub mniej, możesz użyć listy rozwijanej tutaj. Jeśli mogą istnieć tysiące kont użytkowników, warto dołączyć interfejs użytkownika, który umożliwia odwiedzającym stronicowanie za pośrednictwem kont, wyszukiwanie określonego konta lub filtrowanie kont użytkowników w inny sposób.
Na tej stronie użyjemy bardzo prostego interfejsu, który działa niezależnie od liczby kont użytkowników w systemie. Na przykład użyjemy pola TextBox z monitem o wpisanie nazwy użytkownika użytkownika, który chce dodać do wybranej roli. Jeśli żaden użytkownik o tej nazwie nie istnieje lub jeśli użytkownik jest już członkiem roli, zostanie wyświetlony komunikat w ActionStatus
obszarze Etykieta. Jeśli jednak użytkownik istnieje i nie jest członkiem roli, dodamy je do roli i odświeżymy siatkę.
Dodaj pole tekstowe i przycisk poniżej kontrolki GridView. Ustaw wartości TextBox ID
UserNameToAddToRole
na i ustaw odpowiednio właściwości i Text
przycisk ID
na AddUserToRoleButton
i "Dodaj użytkownika do roli".
<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>
Następnie utwórz procedurę Click
obsługi zdarzeń dla elementu AddUserToRoleButton
i dodaj następujący kod:
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); }
Większość kodu w procedurze Click
obsługi zdarzeń wykonuje różne kontrole poprawności. Gwarantuje to, że odwiedzający podał nazwę użytkownika w polu UserNameToAddToRole
TextBox, że użytkownik istnieje w systemie i że nie należy jeszcze do wybranej roli. Jeśli którykolwiek z tych testów zakończy się niepowodzeniem, zostanie wyświetlony ActionStatus
odpowiedni komunikat i program obsługi zdarzeń zostanie zakończona. Jeśli wszystkie testy przejdą, użytkownik zostanie dodany do roli za pomocą Roles.AddUserToRole
metody . Następnie właściwość TextBox Text
zostanie wyczyszczone, widok GridView zostanie odświeżony, a etykieta ActionStatus
wyświetli komunikat wskazujący, że określony użytkownik został pomyślnie dodany do wybranej roli.
Uwaga
Aby upewnić się, że określony użytkownik nie należy jeszcze do wybranej roli, użyjemy Roles.IsUserInRole(userName, roleName)
metody , która zwraca wartość logiczną wskazującą, czy userName jest członkiem roleName. Ta metoda zostanie ponownie użyta w następnym samouczku, gdy przyjrzymy się autoryzacji opartej na rolach.
Odwiedź stronę za pośrednictwem przeglądarki i wybierz rolę Nadzorcy z listy rozwijanej RoleList
. Spróbuj wprowadzić nieprawidłową nazwę użytkownika — powinien zostać wyświetlony komunikat wyjaśniający, że użytkownik nie istnieje w systemie.
Rysunek 9. Nie można dodać użytkownika nieistniejącego do roli (kliknij, aby wyświetlić obraz pełnowymiarowy)
Teraz spróbuj dodać prawidłowego użytkownika. Przejdź do przodu i ponownie dodaj Tito do roli Nadzorcy.
Rysunek 10. Tito jest po raz kolejny przełożonym! (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 3. Krzyżowe aktualizowanie interfejsów "Według użytkownika" i "Według roli"
Strona UsersAndRoles.aspx
oferuje dwa odrębne interfejsy do zarządzania użytkownikami i rolami. Obecnie te dwa interfejsy działają niezależnie od siebie, więc istnieje możliwość, że zmiana w jednym interfejsie nie zostanie odzwierciedlona natychmiast w drugiej. Załóżmy na przykład, że odwiedzający stronę wybiera rolę Nadzorcy z listy Rozwijanej RoleList
, która wyświetla listę Bruce'a i Tito jako członków. Następnie odwiedzający wybierze pozycję Tito z listy rozwijanej UserList
, która sprawdza pola wyboru Administratorzy i nadzorcy w UsersRoleList
repeaterze. Jeśli gość usunie zaznaczenie roli Nadzorca z repeater, Tito zostanie usunięty z roli Nadzorcy, ale ta modyfikacja nie zostanie odzwierciedlona w interfejsie "według roli". Funkcja GridView nadal będzie pokazywać Tito jako członka roli Nadzorcy.
Aby rozwiązać ten problem, musimy odświeżyć kontrolkę GridView za każdym razem, gdy rola jest zaznaczona lub nie jest zaznaczona z elementu UsersRoleList
Repeater. Podobnie musimy odświeżyć repeater za każdym razem, gdy użytkownik zostanie usunięty lub dodany do roli z interfejsu "by role".
Moduł powtarzający w interfejsie "by user" jest odświeżany przez wywołanie CheckRolesForSelectedUser
metody . Interfejs "by role" można zmodyfikować w RolesUserList
procedurze obsługi zdarzeń usługi GridView RowDeleting
i AddUserToRoleButton
procedurze obsługi zdarzeń przycisku Click
. Dlatego musimy wywołać metodę CheckRolesForSelectedUser
z każdej z tych 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();
}
Podobnie element GridView w interfejsie "by role" jest odświeżany przez wywołanie DisplayUsersBelongingToRole
metody, a interfejs "by user" jest modyfikowany za pośrednictwem procedury obsługi zdarzeń RoleCheckBox_CheckChanged
. W związku z tym musimy wywołać metodę DisplayUsersBelongingToRole
z tej procedury obsługi zdarzeń.
protected void RoleCheckBox_CheckChanged(object sender, EventArgs e)
{
... Code removed for brevity...
// Refresh the "by role" interface
DisplayUsersBelongingToRole();
}
Dzięki tym drobnym zmianom kodu interfejsy "by user" i "by role" są teraz poprawnie aktualizowane krzyżowo. Aby to sprawdzić, odwiedź stronę za pośrednictwem przeglądarki i wybierz odpowiednio pozycje Tito i Nadzorcy z UserList
listy rozwijanej i RoleList
Rozwijanej. Pamiętaj, że po usunięciu zaznaczenia roli Nadzorcy dla Tito z repeater w interfejsie "by user" Tito jest automatycznie usuwany z kontrolki GridView w interfejsie "by role". Dodanie Tito z powrotem do roli Nadzorcy z interfejsu "by role" automatycznie ponownie sprawdza pole wyboru Nadzorcy w interfejsie "by user".
Krok 4. Dostosowywanie elementu CreateUserWizard w celu uwzględnienia kroku "Określanie ról"
W samouczku Tworzenie kont użytkowników zobaczyliśmy, jak za pomocą kontrolki CreateUserWizard Web udostępnić interfejs do tworzenia nowego konta użytkownika. Kontrolka CreateUserWizard może być używana na jeden z dwóch sposobów:
- Jako środek dla odwiedzających tworzenie własnego konta użytkownika w witrynie i
- Jako środek dla administratorów do tworzenia nowych kont
W pierwszym przypadku użycia odwiedzający przychodzi do witryny i wypełnia wartość CreateUserWizard, wprowadzając informacje w celu zarejestrowania się w witrynie. W drugim przypadku administrator tworzy nowe konto dla innej osoby.
Gdy konto jest tworzone przez administratora dla innej osoby, może być przydatne zezwolenie administratorowi na określenie ról, do których należy nowe konto użytkownika. W samouczku Przechowywaniedodatkowych informacji o użytkowniku zobaczyliśmy, jak dostosować element CreateUserWizard przez dodanie dodatkowego WizardSteps
elementu . Przyjrzyjmy się, jak dodać dodatkowy krok do elementu CreateUserWizard w celu określenia ról nowego użytkownika.
CreateUserWizardWithRoles.aspx
Otwórz stronę i dodaj kontrolkę CreateUserWizard o nazwie RegisterUserWithRoles
. Ustaw właściwość kontrolki ContinueDestinationPageUrl
na "~/Default.aspx". Ponieważ chodzi tutaj o to, że administrator będzie używać tej kontrolki CreateUserWizard do tworzenia nowych kont użytkowników, ustaw właściwość kontrolki LoginCreatedUser
na False. Ta LoginCreatedUser
właściwość określa, czy gość jest automatycznie zalogowany jako właśnie utworzony użytkownik, i domyślnie ma wartość True. Ustawiliśmy go na wartość Fałsz, ponieważ gdy administrator tworzy nowe konto, chcemy, aby był zalogowany jako sam.
Następnie wybierz pozycję "Dodaj/Usuń WizardSteps
..." opcja z tagu inteligentnego CreateUserWizard i dodaj nowy WizardStep
element , ustawiając wartość ID
na SpecifyRolesStep
. Przenieś element SpecifyRolesStep WizardStep
tak, aby był dostępny po kroku "Zarejestruj się w nowym koncie", ale przed krokiem "Complete" (Ukończ). WizardStep
Ustaw właściwość "sTitle
" na "Określ role", jej StepType
właściwość na Step
, a jej AllowReturn
właściwość na Wartość False.
Rysunek 11. Dodawanie "Określ role" WizardStep
do elementu CreateUserWizard (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po tej zmianie znacznik deklaratywny createUserWizard powinien wyglądać następująco:
<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>
W obszarze "Określ role" WizardStep
dodaj element CheckBoxList o nazwie RoleList
. Ta lista CheckBoxList wyświetli listę dostępnych ról, umożliwiając osobie odwiedzającej stronę sprawdzenie, do jakich ról należy nowo utworzony użytkownik.
Pozostajemy z dwoma zadaniami kodowania: najpierw musimy wypełnić RoleList
listę CheckBoxList rolami w systemie. Po drugie musimy dodać utworzonego użytkownika do wybranych ról, gdy użytkownik przejdzie z kroku "Określ role" do kroku "Ukończono". Możemy wykonać pierwsze zadanie w procedurze obsługi zdarzeń Page_Load
. Poniższy kod programowo odwołuje się do kontrolki RoleList
CheckBox podczas pierwszej wizyty na stronie i wiąże role w systemie z nim.
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();
}
}
Powyższy kod powinien wyglądać znajomo. W samouczku Przechowywaniedodatkowych informacji o użytkowniku użyliśmy dwóch FindControl
instrukcji, aby odwołać się do kontrolki sieci Web z poziomu niestandardowego WizardStep
elementu . Kod, który wiąże role z listą CheckBoxList, został pobrany z wcześniejszej wersji tego samouczka.
Aby wykonać drugie zadanie programistyczne, musimy wiedzieć, kiedy krok "Określ role" został ukończony. Pamiętaj, że zdarzenie CreateUserWizard jest ActiveStepChanged
uruchamiane za każdym razem, gdy odwiedzający przechodzi od jednego kroku do drugiego. W tym miejscu możemy określić, czy użytkownik osiągnął krok "Ukończono"; jeśli tak, musimy dodać użytkownika do wybranych ról.
Utwórz procedurę obsługi zdarzeń ActiveStepChanged
dla zdarzenia i dodaj następujący kod:
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);
}
}
}
Jeśli użytkownik właśnie osiągnął krok "Ukończono", program obsługi zdarzeń wylicza elementy RoleList
CheckBoxList i właśnie utworzony użytkownik zostanie przypisany do wybranych ról.
Odwiedź tę stronę za pośrednictwem przeglądarki. Pierwszym krokiem w artykule CreateUserWizard jest standardowy krok "Zarejestruj się na nowe konto", który wyświetla monit o nazwę użytkownika, hasło, adres e-mail i inne informacje o kluczu. Wprowadź informacje, aby utworzyć nowego użytkownika o nazwie Wanda.
Rysunek 12. Tworzenie nowego użytkownika o nazwie Wanda (kliknij, aby wyświetlić obraz pełnowymiarowy)
Kliknij przycisk "Utwórz użytkownika". Element CreateUserWizard wewnętrznie wywołuje metodę Membership.CreateUser
, tworząc nowe konto użytkownika, a następnie przechodzi do następnego kroku "Określ role". W tym miejscu są wyświetlane role systemowe. Zaznacz pole wyboru Nadzorcy i kliknij przycisk Dalej.
Rysunek 13. Utwórz Wanda członka roli nadzorców (kliknij, aby wyświetlić obraz pełnowymiarowy)
Kliknięcie przycisku Dalej powoduje powrót i zaktualizowanie ActiveStep
kroku "Ukończono". W programie obsługi zdarzeń ActiveStepChanged
ostatnio utworzone konto użytkownika jest przypisywane do roli Nadzorcy. Aby to sprawdzić, wróć do UsersAndRoles.aspx
strony i wybierz pozycję Nadzorcy z listy rozwijanej RoleList
. Jak pokazano na rysunku 14, nadzorcy składają się teraz z trzech użytkowników: Bruce'a, Tito i Wandy.
Rysunek 14. Bruce, Tito i Wanda to Wszyscy nadzorcy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Podsumowanie
Struktura Role oferuje metody pobierania informacji o rolach i metodach określonego użytkownika w celu określenia, do czego należą użytkownicy do określonej roli. Ponadto istnieje wiele metod dodawania i usuwania co najmniej jednego użytkownika do co najmniej jednej roli. W tym samouczku skupiliśmy się tylko na dwóch z następujących metod: AddUserToRole
i RemoveUserFromRole
. Istnieją dodatkowe warianty służące do dodawania wielu użytkowników do jednej roli i przypisywania wielu ról do jednego użytkownika.
W tym samouczku przedstawiono również rozszerzenie kontrolki CreateUserWizard w celu uwzględnienia elementu w WizardStep
celu określenia nowo utworzonych ról użytkownika. Taki krok może pomóc administratorowi usprawnić proces tworzenia kont użytkowników dla nowych użytkowników.
W tym momencie widzieliśmy, jak tworzyć i usuwać role oraz jak dodawać i usuwać użytkowników z ról. Ale musimy jeszcze przyjrzeć się zastosowaniu autoryzacji opartej na rolach. W poniższym samouczku przyjrzymy się zdefiniowaniu reguł autoryzacji adresów URL w oparciu o rolę, a także o tym, jak ograniczyć funkcjonalność na poziomie strony na podstawie aktualnie zalogowanych ról użytkownika.
Szczęśliwe programowanie!
Dalsze informacje
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- ASP.NET Narzędzia administracyjne witryny sieci Web — omówienie
- Badanie platformy ASP. Członkostwo, role i profil platformy NET
Informacje o autorze
Scott Mitchell, autor wielu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Scott można dotrzeć pod mitchell@4guysfromrolla.com adresem lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.
Specjalne podziękowania...
Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka była Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi linię na mitchell@4GuysFromRolla.com