Назначение ролей пользователям (C#)Assigning Roles to Users (C#)

по Скотт Митчеллby Scott Mitchell

Скачать код или скачать PDFDownload Code or Download PDF

В этом учебнике мы создадим две ASP.NET страницы для помощи в управлении тем, к каким ролям относятся пользователи.In this tutorial we will build two ASP.NET pages to assist with managing what users belong to what roles. На первой странице будут включены средства для просмотра пользователей, принадлежащих к определенной роли, роли, к которым принадлежит конкретный пользователь, и возможность назначать или удалять конкретного пользователя из определенной роли.The first page will include facilities to see what users belong to a given role, what roles a particular user belongs to, and the ability to assign or remove a particular user from a particular role. На второй странице мы дополним элемент управления CreateUserWizard таким образом, чтобы он включал в себя шаг для указания ролей, к которым принадлежит только что созданный пользователь.In the second page we will augment the CreateUserWizard control so that it includes a step to specify what roles the newly created user belongs to. Это полезно в сценариях, где администратор может создавать учетные записи пользователей.This is useful in scenarios where an administrator is able to create new user accounts.

ВведениеIntroduction

В предыдущем учебнике рассматривалась платформа ролей и SqlRoleProvider; Мы увидели, как использовать класс Roles для создания, извлечения и удаления ролей.The previous tutorial examined the Roles framework and the SqlRoleProvider; we saw how to use the Roles class to create, retrieve, and delete roles. Помимо создания и удаления ролей, необходимо иметь возможность назначать или удалять пользователей из роли.In addition to creating and deleting roles, we need to be able to assign or remove users from a role. К сожалению, ASP.NET не поставляется с веб-элементами управления для управления тем, к каким ролям относятся пользователи.Unfortunately, ASP.NET does not ship with any Web controls for managing what users belong to what roles. Вместо этого для управления этими ассоциациями необходимо создать собственные страницы ASP.NET.Instead, we must create our own ASP.NET pages to manage these associations. Хорошая новость заключается в том, что добавление и удаление пользователей в роли довольно просто.The good news is that adding and removing users to roles is quite easy. Класс Roles содержит несколько методов для добавления одного или нескольких пользователей к одной или нескольким ролям.The Roles class contains a number of methods for adding one or more users to one or more roles.

В этом учебнике мы создадим две ASP.NET страницы для помощи в управлении тем, к каким ролям относятся пользователи.In this tutorial we will build two ASP.NET pages to assist with managing what users belong to what roles. На первой странице будут включены средства для просмотра пользователей, принадлежащих к определенной роли, роли, к которым принадлежит конкретный пользователь, и возможность назначать или удалять конкретного пользователя из определенной роли.The first page will include facilities to see what users belong to a given role, what roles a particular user belongs to, and the ability to assign or remove a particular user from a particular role. На второй странице мы дополним элемент управления CreateUserWizard таким образом, чтобы он включал в себя шаг для указания ролей, к которым принадлежит только что созданный пользователь.In the second page we will augment the CreateUserWizard control so that it includes a step to specify what roles the newly created user belongs to. Это полезно в сценариях, где администратор может создавать учетные записи пользователей.This is useful in scenarios where an administrator is able to create new user accounts.

Приступим.Let's get started!

Вывод списка пользователей, которым принадлежит рольListing What Users Belong To What Roles

Первый порядок бизнес-процессов для этого руководства — создание веб-страницы, с которой пользователи могут назначаться ролям.The first order of business for this tutorial is to create a web page from which users can be assigned to roles. Прежде чем мы соберемся с тем, как назначать роли пользователям, давайте сначала рассмотрим, как определить, к каким ролям относятся пользователи.Before we concern ourselves with how to assign users to roles, let's first concentrate on how to determine what users belong to what roles. Существует два способа отобразить эту информацию: "по роли" или "по пользователю".There are two ways to display this information: "by role" or "by user." Можно позволить посетителю выбрать роль, а затем показать ее всех пользователей, принадлежащих роли ("по роли"), или предложить посетителю выбрать пользователя и показать ему роли, назначенные этому пользователю (отображение "по пользователю").We could allow the visitor to select a role and then show them all of the users that belong to the role (the "by role" display), or we could prompt the visitor to select a user and then show them the roles assigned to that user (the "by user" display).

Представление "по роли" полезно в тех случаях, когда посетитель хочет узнать набор пользователей, принадлежащих к определенной роли. представление "по пользователю" идеально подходит, когда посетителю нужно узнать, какие роли определенного пользователя.The "by role" view is useful in circumstances where the visitor wants to know the set of users that belong to a particular role; the "by user" view is ideal when the visitor needs to know a particular user's role(s). Пусть наша страница включает интерфейсы "по ролям" и "по пользователям".Let's have our page include both "by role" and "by user" interfaces.

Начнем с создания интерфейса "по пользователю".We will start with creating the "by user" interface. Этот интерфейс будет состоять из раскрывающегося списка и списка флажков.This interface will consist of a drop-down list and a list of checkboxes. Раскрывающийся список будет заполнен набором пользователей в системе; флажки будут перечислять роли.The drop-down list will be populated with the set of users in the system; the checkboxes will enumerate the roles. При выборе пользователя в раскрывающемся списке будут проверены роли, к которым принадлежит пользователь.Selecting a user from the drop-down list will check those roles the user belongs to. Пользователь, посещающий страницу, может установить или снять флажки, чтобы добавить или удалить выбранного пользователя из соответствующих ролей.The person visiting the page can then check or uncheck the checkboxes to add or remove the selected user from the corresponding roles.

Note

Использование раскрывающегося списка для перечисления учетных записей пользователей не является идеальным выбором для веб-сайтов, где могут быть сотни учетных записей пользователей.Using a drop-down list to list the user accounts is not an ideal choice for websites where there may be hundreds of user accounts. Раскрывающийся список предназначен для того, чтобы позволить пользователю выбрать один элемент из относительно короткого списка параметров.A drop-down list is designed to allow a user to pick one item from a relatively short list of options. Это быстро становится неудобной, так как количество элементов в списке растет.It quickly becomes unwieldy as the number of list items grows. Если вы создаете веб-сайт, который будет потенциально большим числом учетных записей пользователей, можно рассмотреть возможность использования альтернативного пользовательского интерфейса, такого как страничный GridView или интерфейс с фильтрацией, который предлагает посетителю выбрать письмо и только потом показывает пользователей, имена которых начинаются с выбранной буквы.If you are building a website that will have potentially large numbers of user accounts, you may want to consider using an alternative user interface, such as a pageable GridView or a filterable interface that lists prompts the visitor to choose a letter and then only shows those users whose username starts with the selected letter.

Шаг 1. Создание пользовательского интерфейса "по пользователю"Step 1: Building the "By User" User Interface

Откройте страницу UsersAndRoles.aspx.Open the UsersAndRoles.aspx page. В верхней части страницы добавьте элемент управления Label с именем ActionStatus и удалите его свойство Text.At the top of the page, add a Label Web control named ActionStatus and clear out its Text property. Мы будем использовать эту метку для предоставления отзывов о выполняемых действиях, отображая такие сообщения, как "пользователь Тито был добавлен в роль" Администраторы ", или" пользователь Цзисунь был удален из роли "руководители".We will use this Label to provide feedback on the actions performed, displaying messages like, "User Tito has been added to the Administrators role," or "User Jisun has been removed from the Supervisors role." Чтобы эти сообщения были выделены, присвойте свойству CssClass метки значение "важно".In order to make these messages stand out, set the Label's CssClass property to "Important".

<p align="center"> 

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

Затем добавьте следующее определение класса CSS в таблицу стилей Styles.css:Next, add the following CSS class definition to the Styles.css stylesheet:

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

Это определение CSS указывает браузеру отображать метку с помощью большого красного шрифта.This CSS definition instructs the browser to display the Label using a large, red font. На рис. 1 показан этот результат в конструкторе Visual Studio.Figure 1 shows this effect through the Visual Studio Designer.

свойство CssClass метки получает большой красный шрифтThe Label's CssClass Property Results in a Large, Red Font

Рис. 1. свойство CssClass метки приводит к большому красному шрифту (щелкните, чтобы просмотреть изображение с полным размером).Figure 1: The Label's CssClass Property Results in a Large, Red Font (Click to view full-size image)

Затем добавьте элемент DropDownList на страницу, задайте для его свойства ID значение UserListи задайте для свойства AutoPostBack значение true.Next, add a DropDownList to the page, set its ID property to UserList, and set its AutoPostBack property to True. Мы будем использовать этот элемент DropDownList для вывода списка всех пользователей в системе.We will use this DropDownList to list all of the users in the system. Это DropDownList будет привязан к коллекции объектов MembershipUser.This DropDownList will be bound to a collection of MembershipUser objects. Так как элементу DropDownList нужно отобразить свойство UserName объекта MembershipUser (и использовать его в качестве значения элементов списка), задайте для свойств DataTextField и DataValueField DropDownList значение UserName.Because we want the DropDownList to display the UserName property of the MembershipUser object (and use it as the value of the list items), set the DropDownList's DataTextField and DataValueField properties to "UserName".

Под элементом DropDownList добавьте элемент Repeater с именем UsersRoleList.Underneath the DropDownList, add a Repeater named UsersRoleList. Этот Repeater будет перечислять все роли в системе в виде ряда флажков.This Repeater will list all of the roles in the system as a series of checkboxes. Определите ItemTemplate Repeater, используя следующую декларативную разметку:Define the Repeater's ItemTemplate using the following declarative markup:

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

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

Разметка ItemTemplate включает один веб-элемент управления CheckBox с именем RoleCheckBox.The ItemTemplate markup includes a single CheckBox Web control named RoleCheckBox. AutoPostBack свойству CheckBox присвоено значение true, а свойство Text привязано к Container.DataItem.The CheckBox's AutoPostBack property is set to True and the Text property is bound to Container.DataItem. Причина, по которой синтаксис DataBinding является просто Container.DataItem, заключается в том, что платформа ролей возвращает список имен ролей в виде массива строк, и это строковый массив, который мы будем привязать к элементу Repeater.The reason the databinding syntax is simply Container.DataItem is because the Roles framework returns the list of role names as a string array, and it is this string array that we will be binding to the Repeater. Подробное описание того, почему этот синтаксис используется для вывода содержимого массива, привязанного к веб-элементу управления данными, выходит за рамки данного руководства.A thorough description of why this syntax is used to display the contents of an array bound to a data Web control is beyond the scope of this tutorial. Дополнительные сведения об этом важностях см. в статье Привязка скалярного массива к веб-элементу управления данными.For more information on this matter, refer to Binding a Scalar Array to a Data Web Control.

На этом этапе декларативная разметка интерфейса "по пользователю" должна выглядеть следующим образом:At this point your "by user" interface's declarative markup should look similar to the following:

<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.We are now ready to write the code to bind the set of user accounts to the DropDownList and the set of roles to the Repeater. В классе кода программной части страницы добавьте метод с именем BindUsersToUserList и другой с именем BindRolesList, используя следующий код:In the page's code-behind class, add a method named BindUsersToUserList and another named BindRolesList, using the following code:

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.The BindUsersToUserList method retrieves all of the user accounts in the system via the Membership.GetAllUsers method. Он возвращает объектMembershipUserCollection, который представляет собой коллекцию экземпляровMembershipUser.This returns a MembershipUserCollection object, which is a collection of MembershipUser instances. Затем эта коллекция привязывается к элементу DropDownList UserList.This collection is then bound to the UserList DropDownList. Экземпляры MembershipUser, описывающего коллекцию, содержат различные свойства, такие как UserName, Email, CreationDateи IsOnline.The MembershipUser instances that makeup the collection contain a variety of properties, like UserName, Email, CreationDate, and IsOnline. Чтобы элементу DropDownList отображалось значение свойства UserName, убедитесь UserList, что свойства DataTextField и DataValueField элемента DropDownList установлены в значение UserName.In order to instruct the DropDownList to display the value of the UserName property, ensure that the UserList DropDownList's DataTextField and DataValueField properties have been set to "UserName".

Note

Метод Membership.GetAllUsers имеет две перегрузки: один, который не принимает входные параметры и возвращает всех пользователей, а второй принимает целочисленные значения для индекса страницы и размера страницы и возвращает только указанное подмножество пользователей.The Membership.GetAllUsers method has two overloads: one that accepts no input parameters and returns all of the users, and one that takes in integer values for the page index and page size, and returns only the specified subset of the users. Если в элементе пользовательского интерфейса, доступном для просмотра, отображаются большие объемы учетных записей пользователей, вторая перегрузка может быть использована для более эффективной страницы пользователей, поскольку она возвращает только точное подмножество учетных записей пользователей, а не все из них.When there are large amounts of user accounts being displayed in a pageable user interface element, the second overload can be used to more efficiently page through the users since it returns just the precise subset of user accounts rather than all of them.

Метод BindRolesToList начинается с вызова методаGetAllRolesкласса Roles, который возвращает массив строк, содержащий роли в системе.The BindRolesToList method starts by calling the Roles class's GetAllRoles method, which returns a string array containing the roles in the system. Затем этот строковый массив привязывается к элементу Repeater.This string array is then bound to the Repeater.

Наконец, необходимо вызвать эти два метода при первой загрузке страницы.Finally, we need to call these two methods when the page is first loaded. Добавьте следующий код в обработчик событий Page_Load .Add the following code to the Page_Load event handler:

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

Выполнив этот код, уделите время посетить страницу в браузере. экран должен выглядеть примерно так, как показано на рис. 2.With this code in place, take a moment to visit the page through a browser; your screen should look similar to Figure 2. Все учетные записи пользователей заполняются в раскрывающемся списке, и под ним каждая роль отображается как флажок.All of the user accounts are populated in the drop-down list and, underneath that, each role appears as a checkbox. Так как мы устанавливаем свойства AutoPostBack DropDownList и CheckBoxs равными true, изменение выбранного пользователя или проверка или депроверка роли приводит к выполнению обратной передачи.Because we set the AutoPostBack properties of the DropDownList and CheckBoxes to True, changing the selected user or checking or unchecking a role causes a postback. Однако никакие действия не выполняются, так как мы еще не написали код для решения этих действий.No action is performed, however, because we have yet to write code to handle these actions. Эти задачи будут рассмотрены в следующих двух разделах.We'll tackle these tasks in the next two sections.

странице отображаются пользователи и роли.The Page Displays the Users and Roles

Рис. 2. на странице отображаются пользователи и роли (щелкните, чтобы просмотреть изображение с полным размером)Figure 2: The Page Displays the Users and Roles (Click to view full-size image)

Проверка ролей, к которым принадлежит выбранный пользовательChecking the Roles the Selected User Belongs To

При первой загрузке страницы или когда посетитель выбирает нового пользователя из раскрывающегося списка, необходимо обновить флажки UsersRoleList, чтобы флажок запускался только в том случае, если выбранный пользователь принадлежит к этой роли.When the page is first loaded, or whenever the visitor selects a new user from the drop-down list, we need to update the UsersRoleList's checkboxes so that a given role checkbox is checked only if the selected user belongs to that role. Для этого создайте метод с именем CheckRolesForSelectedUser со следующим кодом:To accomplish this, create a method named CheckRolesForSelectedUser with the following code:

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

Приведенный выше код начинается с определения того, кто является выбранным пользователем.The above code starts by determining who the selected user is. Затем он использует методGetRolesForUser(userName) класса Roles для возврата набора ролей указанного пользователя в виде массива строк.It then uses the Roles class's GetRolesForUser(userName) method to return the specified user's set of roles as a string array. Далее производится перечисление элементов Repeater и установлен флажок RoleCheckBox каждого элемента в программной ссылке.Next, the Repeater's items are enumerated and each item's RoleCheckBox CheckBox is programmatically referenced. Флажок проверяется только в том случае, если роль, к которой он соответствует, содержится в selectedUsersRoles массиве строк.The CheckBox is checked only if the role it corresponds to is contained within the selectedUsersRoles string array.

Note

Синтаксис selectedUserRoles.Contains<string>(...) не будет компилироваться, если используется ASP.NET версии 2,0.The selectedUserRoles.Contains<string>(...) syntax will not compile if you are using ASP.NET version 2.0. Метод Contains<string> является частью библиотеки LINQ, которая является новой для ASP.NET 3,5.The Contains<string> method is part of the LINQ library, which is new to ASP.NET 3.5. Если вы все еще используете ASP.NET версии 2,0, используйте вместо этого методArray.IndexOf<string> .If you are still using ASP.NET version 2.0, use the Array.IndexOf<string> method instead.

Метод CheckRolesForSelectedUser должен вызываться в двух случаях: при первой загрузке страницы и изменении выбранного индекса DropDownList UserList.The CheckRolesForSelectedUser method needs to be called in two cases: when the page is first loaded and whenever the UserList DropDownList's selected index is changed. Поэтому Вызывайте этот метод из обработчика событий Page_Load (после вызовов BindUsersToUserList и BindRolesToList).Therefore, call this method from the Page_Load event handler (after the calls to BindUsersToUserList and BindRolesToList). Кроме того, создайте обработчик событий для события SelectedIndexChanged DropDownList и вызовите этот метод из него.Also, create an event handler for the DropDownList's SelectedIndexChanged event and call this method from there.

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

С помощью этого кода можно протестировать страницу в браузере.With this code in place, you can test the page through the browser. Тем не менее, поскольку на UsersAndRoles.aspxной странице в настоящее время нет возможности назначать пользователям роли, пользователи не имеют ролей.However, since the UsersAndRoles.aspx page currently lacks the ability to assign users to roles, no users have roles. Мы создадим интерфейс для назначения пользователям ролей в течение некоторого времени, так что вы можете взять слово, чтобы этот код работал, и проверить, что он делает это позже, или можно вручную добавить пользователей к ролям, вставив записи в таблицу aspnet_UsersInRoles, чтобы протестировать эту функцию прямо сейчас.We will create the interface for assigning users to roles in a moment, so you can either take my word that this code works and verify that it does so later, or you can manually add users to roles by inserting records into the aspnet_UsersInRoles table in order to test this functionality now.

Назначение и удаление пользователей из ролейAssigning and Removing Users from Roles

Когда посетитель проверяет или снимает флажок в UsersRoleList Repeater, необходимо добавить или удалить выбранного пользователя из соответствующей роли.When the visitor checks or unchecks a CheckBox in the UsersRoleList Repeater we need to add or remove the selected user from the corresponding role. Свойство AutoPostBack CheckBox в настоящее время имеет значение true, что приводит к тому, что флажок в элементе Repeater будет установлен или снят.The CheckBox's AutoPostBack property is currently set to True, which causes a postback anytime a CheckBox in the Repeater is checked or unchecked. Вкратце, нам нужно создать обработчик событий для CheckChanged события CheckBox.In short, we need to create an event handler for the CheckBox's CheckChanged event. Поскольку флажок находится в элементе управления Repeater, необходимо вручную добавить коммуникации обработчика событий.Since the CheckBox is in a Repeater control, we need to manually add the event handler plumbing. Начните с добавления обработчика событий в класс кода программной части в качестве метода protected, например так:Start by adding the event handler to the code-behind class as a protected method, like so:

protected void RoleCheckBox_CheckChanged(object sender, EventArgs e) 
{ 

}

В данный момент мы вернемся к написанию кода для этого обработчика событий.We will return to write the code for this event handler in a moment. Но сначала выполним обработку событий.But first let's complete the event handling plumbing. Из флажка в ItemTemplateе Repeater добавьте OnCheckedChanged="RoleCheckBox_CheckChanged".From the CheckBox within the Repeater's ItemTemplate, add OnCheckedChanged="RoleCheckBox_CheckChanged". Этот синтаксис связывает обработчик событий RoleCheckBox_CheckChanged с событием CheckedChanged RoleCheckBox.This syntax wires the RoleCheckBox_CheckChanged event handler to the RoleCheckBox's CheckedChanged event.

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

Наша последняя задача — завершить обработчик событий RoleCheckBox_CheckChanged.Our final task is to complete the RoleCheckBox_CheckChanged event handler. Нам нужно начать с ссылки на элемент управления CheckBox, который вызвал событие, поскольку этот экземпляр CheckBox указывает, какая роль была проверена или снята с помощью свойств Text и Checked.We need to start by referencing the CheckBox control that raised the event because this CheckBox instance tells us what role was checked or unchecked via its Text and Checked properties. Используя эти сведения вместе с именем пользователя выбранного пользователя, мы добавляем или удаляю пользователя из роли с помощью метода AddUserToRole или RemoveUserFromRoleкласса Roles.Using this information along with the UserName of the selected user, we add or remove the user from the role via the Roles class's AddUserToRole or RemoveUserFromRole method.

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

     } 
}

Приведенный выше код начинается с программной ссылки на флажок, вызвавший событие, которое доступно через входной параметр sender.The above code starts by programmatically referencing the CheckBox that raised the event, which is available via the sender input parameter. Если флажок установлен, выбранный пользователь добавляется к указанной роли, в противном случае он удаляется из роли.If the CheckBox is checked, the selected user is added to the specified role, otherwise they are removed from the role. В любом случае в метке ActionStatus отображается сообщение с описанием только что выполненного действия.In either case, the ActionStatus Label displays a message summarizing the action just performed.

Уделите время на тестирование этой страницы в браузере.Take a moment to test out this page through a browser. Выберите пользователь Тито, а затем добавьте Тито в роли Администраторы и Супервизоры.Select user Tito and then add Tito to both the Administrators and Supervisors roles.

Тито добавлена в роли администраторов и руководителей.Tito Has Been Added to the Administrators and Supervisors Roles

Рис. 3. Тито добавлены в роли администраторов и руководителей (щелкните, чтобы просмотреть изображение с полным размером)Figure 3: Tito Has Been Added to the Administrators and Supervisors Roles (Click to view full-size image)

Затем в раскрывающемся списке Выберите User Брюс (пользователь).Next, select user Bruce from the drop-down list. Обратная передача и флажки Repeater обновляются с помощью CheckRolesForSelectedUser.There is a postback and the Repeater's CheckBoxes are updated via the CheckRolesForSelectedUser. Так как Брюс еще не принадлежит ни одной роли, два флажка не устанавливаются.Since Bruce does not yet belong to any roles, the two checkboxes are unchecked. Затем добавьте Брюс в роль супервизоров.Next, add Bruce to the Supervisors role.

Брюс добавлена в роль "руководители"Bruce Has Been Added to the Supervisors Role

Рис. 4. Брюс был добавлен в роль "руководители" (щелкните, чтобы просмотреть изображение с полным размером)Figure 4: Bruce Has Been Added to the Supervisors Role (Click to view full-size image)

Для дальнейшей проверки функциональности метода CheckRolesForSelectedUser выберите пользователя, отличного от Тито или Брюс.To further verify the functionality of the CheckRolesForSelectedUser method, select a user other than Tito or Bruce. Обратите внимание, что флажки автоматически снимаются, отметив, что они не принадлежат ни к одной роли.Note how the checkboxes are automatically unchecked, denoting that they do not belong to any roles. Вернитесь к Тито.Return to Tito. Должны быть установлены флажки администраторы и Супервизоры.Both the Administrators and Supervisors checkboxes should be checked.

Шаг 2. Создание пользовательского интерфейса "по ролям"Step 2: Building the "By Roles" User Interface

На этом этапе мы завершили работу с интерфейсом "по пользователям" и готовы начать работу с интерфейсом "по ролям".At this point we have completed the "by users" interface and are ready to start tackling the "by roles" interface. Интерфейс "по ролям" предлагает пользователю выбрать роль из раскрывающегося списка, а затем отображает набор пользователей, принадлежащих к этой роли в элементе управления GridView.The "by roles" interface prompts the user to select a role from a drop-down list and then displays the set of users that belong to that role in a GridView.

Добавьте еще один элемент управления DropDownList на страницу UsersAndRoles.aspx.Add another DropDownList control to the UsersAndRoles.aspx page. Поместите его под элементом управления Repeater, назовите его RoleListи присвойте свойству AutoPostBack значение true.Place this one beneath the Repeater control, name it RoleList, and set its AutoPostBack property to True. Ниже добавьте GridView и присвойте ему имя RolesUserList.Underneath that, add a GridView and name it RolesUserList. В этом элементе GridView будут перечислены пользователи, принадлежащие к выбранной роли.This GridView will list the users that belong to the selected role. Задайте для свойства AutoGenerateColumns GridView значение false, добавьте TemplateField в коллекцию Columns сетки и присвойте свойству HeaderText значение "Users".Set the GridView's AutoGenerateColumns property to False, add a TemplateField to the grid's Columns collection, and set its HeaderText property to "Users". Определите ItemTemplate TemplateField, чтобы на нем отображалось значение выражения привязки данных Container.DataItem в свойстве Text метки с именем UserNameLabel.Define the TemplateField's ItemTemplate so that it displays the value of the databinding expression Container.DataItem in the Text property of a Label named UserNameLabel.

После добавления и настройки GridView декларативная разметка интерфейса "по роли" должна выглядеть следующим образом:After adding and configuring the GridView, your "by role" interface's declarative markup should look similar to the following:

<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 набором ролей в системе.We need to populate the RoleList DropDownList with the set of roles in the system. Для этого обновите метод BindRolesToList, чтобы привязать массив строк, возвращаемый методом Roles.GetAllRoles, к RolesList DropDownList (а также к UsersRoleList Repeater).To accomplish this, update the BindRolesToList method so that is binds the string array returned by the Roles.GetAllRoles method to the RolesList DropDownList (as well as the UsersRoleList Repeater).

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

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

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

Последние две строки в методе BindRolesToList были добавлены для привязки набора ролей к элементу управления DropDownList RoleList.The last two lines in the BindRolesToList method have been added to bind the set of roles to the RoleList DropDownList control. На рис. 5 показан конечный результат при просмотре в браузере — раскрывающийся список, заполненный ролями системы.Figure 5 shows the end result when viewed through a browser – a drop-down list populated with the system's roles.

роли отображаются в DropDownList RoleListThe Roles are Displayed in the RoleList DropDownList

Рис. 5. роли отображаются в RoleList DropDownList (щелкните, чтобы просмотреть изображение с полным размером)Figure 5: The Roles are Displayed in the RoleList DropDownList (Click to view full-size image)

Отображение пользователей, принадлежащих выбранной ролиDisplaying the Users That Belong To the Selected Role

При первой загрузке страницы или при выборе новой роли из RoleList DropDownList необходимо отобразить список пользователей, принадлежащих к этой роли в GridView.When the page is first loaded, or when a new role is selected from the RoleList DropDownList, we need to display the list of users that belong to that role in the GridView. Создайте метод с именем DisplayUsersBelongingToRole, используя следующий код:Create a method named DisplayUsersBelongingToRole using the following code:

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

Этот метод начинается с получения выбранной роли из RoleList DropDownList.This method starts by getting the selected role from the RoleList DropDownList. Затем он использует методRoles.GetUsersInRole(roleName) для получения строкового массива имен пользователей, принадлежащих к этой роли.It then uses the Roles.GetUsersInRole(roleName) method to retrieve a string array of the UserNames of the users that belong to that role. Затем этот массив привязывается к RolesUserList GridView.This array is then bound to the RolesUserList GridView.

Этот метод должен вызываться в двух случаях: при начальной загрузке страницы и при изменении выбранной роли в RoleList DropDownList.This method needs to be called in two circumstances: when the page is initially loaded and when the selected role in the RoleList DropDownList changes. Поэтому обновите обработчик событий Page_Load таким образом, чтобы этот метод вызывался после вызова метода CheckRolesForSelectedUser.Therefore, update the Page_Load event handler so that this method is invoked after the call to CheckRolesForSelectedUser. Затем создайте обработчик событий для события SelectedIndexChanged RoleListи вызовите этот метод из него.Next, create an event handler for the RoleList's SelectedIndexChanged event, and call this method from there, too.

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

После этого кода в RolesUserList GridView должны отображаться пользователи, принадлежащие выбранной роли.With this code in place, the RolesUserList GridView should display those users that belong to the selected role. Как показано на рис. 6, роль супервизоров состоит из двух членов: Брюс и Тито.As Figure 6 shows, the Supervisors role consists of two members: Bruce and Tito.

элементе GridView список пользователей, принадлежащих выбранной ролиThe GridView Lists Those Users That Belong to the Selected Role

Рис. 6. список пользователей, принадлежащих выбранной роли (щелкните, чтобы просмотреть изображение с полным размером)Figure 6: The GridView Lists Those Users That Belong to the Selected Role (Click to view full-size image)

Удаление пользователей из выбранной ролиRemoving Users from the Selected Role

Добавим RolesUserList GridView, чтобы он включал столбец с кнопками "Удалить".Let's augment the RolesUserList GridView so that it includes a column of "Remove" buttons. Нажатие кнопки "Удалить" для конкретного пользователя удалит их из этой роли.Clicking the "Remove" button for a particular user will remove them from that role.

Начните с добавления поля кнопки Удалить в GridView.Start by adding a Delete button field to the GridView. Сделайте это поле наиболее заполненным и измените его свойство DeleteText на "Delete" (по умолчанию) на "Remove" (удалить).Make this field appear as the left most filed and change its DeleteText property from "Delete" (the default) to "Remove".

добавитьAdd the

Рис. 7. Добавление кнопки "Удалить" в GridView (щелкните, чтобы просмотреть изображение с полным размером)Figure 7: Add the "Remove" Button to the GridView (Click to view full-size image)

При нажатии кнопки "Удалить" происходит обратная передача, и возникает событие RowDeleting GridView.When the "Remove" button is clicked a postback ensues and the GridView's RowDeleting event is raised. Необходимо создать обработчик событий для этого события и написать код, который удаляет пользователя из выбранной роли.We need to create an event handler for this event and write code that removes the user from the selected role. Создайте обработчик событий, а затем добавьте следующий код:Create the event handler and then add the following code:

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

Код начинается с определения имени выбранной роли.The code starts by determining the selected role name. Затем он программно ссылается на элемент управления UserNameLabel из строки, для которой была нажата кнопка "Удалить", чтобы определить имя пользователя, которого нужно удалить.It then programmatically references the UserNameLabel control from the row whose "Remove" button was clicked in order to determine the UserName of the user to remove. Затем пользователь удаляется из роли с помощью вызова метода Roles.RemoveUserFromRole.The user is then removed from the role via a call to the Roles.RemoveUserFromRole method. После этого RolesUserList GridView обновляется и выводится сообщение с помощью элемента управления Метка ActionStatus.The RolesUserList GridView is then refreshed and a message is displayed via the ActionStatus Label control.

Note

Перед удалением пользователя из роли для кнопки "Удалить" не требуется никаких подтверждений от пользователя.The "Remove" button does not require any sort of confirmation from the user before removing the user from the role. Я предлагаю добавить некоторый уровень подтверждения пользователя.I invite you to add some level of user confirmation. Одним из самых простых способов подтверждения действия является применение диалогового окна подтверждения на стороне клиента.One of the easiest ways to confirm an action is through a client-side confirm dialog box. Дополнительные сведения об этом способе см. в разделе Добавление подтверждения на стороне клиента при удалении.For more information on this technique, see Adding Client-Side Confirmation When Deleting.

На рис. 8 показана страница после удаления пользователя Тито из группы «руководители».Figure 8 shows the page after user Tito has been removed from the Supervisors group.

увы, Тито больше не является супервизоромAlas, Tito is No Longer a Supervisor

Рис. 8. Увы, Тито больше не является супервизором (щелкните, чтобы просмотреть изображение с полным размером)Figure 8: Alas, Tito is No Longer a Supervisor (Click to view full-size image)

Добавление новых пользователей к выбранной ролиAdding New Users to the Selected Role

Вместе с удалением пользователей из выбранной роли посетитель этой страницы также должен иметь возможность добавить пользователя к выбранной роли.Along with removing users from the selected role, the visitor to this page should also be able to add a user to the selected role. Лучший интерфейс для добавления пользователя в выбранную роль зависит от количества учетных записей пользователей, которые вы ожидаете использовать.The best interface for adding a user to the selected role depends on the number of user accounts you expect to have. Если ваш веб-сайт будет размещать всего несколько десятков учетных записей пользователей, можно использовать DropDownList.If your website will house just a few dozen user accounts or less, you could use a DropDownList here. Если могут быть тысячи учетных записей пользователей, необходимо включить пользовательский интерфейс, позволяющий посетителям пролистывать учетные записи, выполнять поиск конкретной учетной записи или фильтровать учетные записи пользователей каким-либо другим способом.If there might be thousands of user accounts, you would want to include a user interface that permits the visitor to page through the accounts, search for a particular account, or filter the user accounts in some other fashion.

Для этой страницы мы будем использовать очень простой интерфейс, который работает независимо от количества учетных записей пользователей в системе.For this page let's use a very simple interface that works regardless of the number of user accounts in the system. А именно, мы будем использовать текстовое поле, предлагающее посетителю ввести имя пользователя, которого пользователь хочет добавить в выбранную роль.Namely, we will use a TextBox, prompting the visitor to type in the username of the user she wants to add to the selected role. Если пользователь с таким именем не существует или пользователь уже является членом роли, в ActionStatus метка будет отображаться сообщение.If no user with that name exists, or if the user is already a member of the role, we'll display a message in ActionStatus Label. Но если пользователь существует и не является членом роли, мы добавим его к роли и обновляем сетку.But if the user exists and is not a member of the role, we'll add them to the role and refresh the grid.

Добавьте текстовое поле и кнопку под элементом GridView.Add a TextBox and Button beneath the GridView. Задайте для текстового поля ID значение UserNameToAddToRole и задайте для свойств ID и Text кнопки значение AddUserToRoleButton и "добавить пользователя в роль" соответственно.Set the TextBox's ID to UserNameToAddToRole and set the Button's ID and Text properties to AddUserToRoleButton and "Add User to Role", respectively.

<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 и добавьте следующий код:Next, create a Click event handler for the AddUserToRoleButton and add the following code:

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 выполняет различные проверки.The majority of the code in the Click event handler performs various validation checks. Это гарантирует, что посетитель указал имя пользователя в текстовом поле UserNameToAddToRole, что пользователь уже существует в системе и не принадлежит выбранной роли.It ensures that the visitor supplied a username in the UserNameToAddToRole TextBox, that the user exists in the system, and that they don't already belong to the selected role. Если какая-либо из этих проверок завершается сбоем, в ActionStatus отображается соответствующее сообщение, а обработчик событий завершает работу.If any of these checks fails, an appropriate message is displayed in ActionStatus and the event handler is exited. Если все проверки пройдены, пользователь добавляется к роли с помощью метода Roles.AddUserToRole.If all of the checks pass, the user is added to the role via the Roles.AddUserToRole method. После этого удаляется свойство Text текстового поля, GridView обновляется, а ActionStatus метка отображает сообщение о том, что указанный пользователь успешно добавлен в выбранную роль.Following that, the TextBox's Text property is cleared out, the GridView is refreshed, and the ActionStatus Label displays a message indicating that the specified user was successfully added to the selected role.

Note

Чтобы убедиться, что указанный пользователь еще не принадлежит выбранной роли, мы используем методRoles.IsUserInRole(userName, roleName), который возвращает логическое значение, указывающее, является ли имя пользователя членом roleName.To ensure that the specified user does not already belong to the selected role, we use the Roles.IsUserInRole(userName, roleName) method, which returns a Boolean value indicating whether userName is a member of roleName. Мы будем использовать этот метод еще раз в следующем руководстве , когда мы рассмотрим авторизацию на основе ролей.We will use this method again in the next tutorial when we look at role-based authorization.

Откройте страницу в браузере и выберите роль супервизоров в RoleList DropDownList.Visit the page through a browser and select the Supervisors role from the RoleList DropDownList. Попробуйте ввести недопустимое имя пользователя. должно отобразиться сообщение о том, что пользователь не существует в системе.Try entering an invalid username – you should see a message explaining that the user does not exist in the system.

нельзя добавить несуществующего пользователя к ролиYou Cannot Add a Non-Existent User to a Role

Рис. 9. невозможно добавить несуществующего пользователя к роли (щелкните, чтобы просмотреть изображение с полным размером)Figure 9: You Cannot Add a Non-Existent User to a Role (Click to view full-size image)

Теперь попробуйте добавить допустимого пользователя.Now try adding a valid user. Снова добавьте Тито в роль супервизоров.Go ahead and re-add Tito to the Supervisors role.

Тито еще раз является супервизором!Tito Is Once Again a Supervisor!

Рис. 10. Тито снова является супервизором!Figure 10: Tito Is Once Again a Supervisor! (Щелкните, чтобы просмотреть изображение с полным размером)(Click to view full-size image)

Шаг 3. Перекрестное обновление интерфейсов "по пользователям" и "по ролям"Step 3: Cross-Updating the "By User" and "By Role" Interfaces

Страница UsersAndRoles.aspx предлагает два отдельных интерфейса для управления пользователями и ролями.The UsersAndRoles.aspx page offers two distinct interfaces for managing users and roles. В настоящее время эти два интерфейса работают независимо друг от друга, поэтому изменение, внесенное в одном интерфейсе, не будет немедленно отражено в другом.Currently, these two interfaces act independently of one another so it is possible that a change made in one interface will not be reflected immediately in the other. Например, представьте, что посетитель страницы выбирает роль супервизоров из RoleList DropDownList, где в качестве членов перечисляются Брюс и Тито.For example, imagine that the visitor to the page selects the Supervisors role from the RoleList DropDownList, which lists Bruce and Tito as its members. Затем посетитель выбирает UserList Тито в элементе DropDownList, который проверяет флажки "Администраторы" и "Супервизоры" в UsersRoleList Repeater.Next, the visitor selects Tito from the UserList DropDownList, which checks the Administrators and Supervisors checkboxes in the UsersRoleList Repeater. Если затем посетитель отменяет роль супервизора от повторителя, Тито удаляется из роли супервизоров, но это изменение не отражается в интерфейсе Role.If the visitor then unchecks the Supervisor role from the Repeater, Tito is removed from the Supervisors role, but this modification is not reflected in the "by role" interface. GridView по-прежнему будет показывать Тито как член роли "руководители".The GridView will still show Tito as being a member of the Supervisors role.

Чтобы исправить это, необходимо обновить GridView при проверке или снятии роли с UsersRoleList Repeater.To fix this we need to refresh the GridView whenever a role is checked or unchecked from the UsersRoleList Repeater. Аналогичным образом, необходимо обновлять Repeater каждый раз, когда пользователь удаляется или добавляется к роли из интерфейса "по роли".Likewise, we need to refresh the Repeater whenever a user is removed or added to a role from the "by role" interface.

Элемент Repeater в интерфейсе "по пользователю" обновляется путем вызова метода CheckRolesForSelectedUser.The Repeater in the "by user" interface is refreshed by calling the CheckRolesForSelectedUser method. Интерфейс "по роли" можно изменить в обработчике событий RowDeleting RolesUserList GridView и обработчике событий Click кнопки AddUserToRoleButton.The "by role" interface can be modified in the RolesUserList GridView's RowDeleting event handler and the AddUserToRoleButton Button's Click event handler. Поэтому необходимо вызвать метод CheckRolesForSelectedUser из каждого из этих методов.Therefore, we need to call the CheckRolesForSelectedUser method from each of these methods.

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

Аналогично, элемент управления GridView в интерфейсе "по роли" обновляется путем вызова метода DisplayUsersBelongingToRole, а интерфейс "по пользователю" изменяется с помощью обработчика событий RoleCheckBox_CheckChanged.Similarly, the GridView in the "by role" interface is refreshed by calling the DisplayUsersBelongingToRole method and the "by user" interface is modified through the RoleCheckBox_CheckChanged event handler. Поэтому нам нужно вызвать метод DisplayUsersBelongingToRole из этого обработчика событий.Therefore, we need to call the DisplayUsersBelongingToRole method from this event handler.

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

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

В результате этих незначительных изменений кода интерфейсы "по пользователям" и "по ролям" теперь правильно перекрестно обновляются.With these minor code changes, the "by user" and "by role" interfaces now correctly cross-update. Чтобы проверить это, перейдите на страницу браузера и выберите Тито и Супервизоры в UserList и RoleList элементов управления DropDownList соответственно.To verify this, visit the page through a browser and select Tito and Supervisors from the UserList and RoleList DropDownLists, respectively. Обратите внимание, что при снятии флажка роли Супервизоры для Тито из Repeater в интерфейсе "по пользователям" Тито автоматически удаляется из GridView в интерфейсе "по ролям".Note that as you uncheck the Supervisors role for Tito from the Repeater in the "by user" interface, Tito is automatically removed from the GridView in the "by role" interface. При добавлении Тито к роли супервизоров из интерфейса "по роли" автоматически проверяется флажок "руководители" в интерфейсе "по пользователям".Adding Tito back to the Supervisors role from the "by role" interface automatically re-checks the Supervisors checkbox in the "by user" interface.

Шаг 4. Настройка CreateUserWizard для включения шага "указание ролей"Step 4: Customizing the CreateUserWizard to Include a "Specify Roles" Step

В учебнике Создание учетных записей пользователей мы увидели, как использовать веб-элемент управления CreateUserWizard, чтобы предоставить интерфейс для создания новой учетной записи пользователя.In the Creating User Accounts tutorial we saw how to use the CreateUserWizard Web control to provide an interface for creating a new user account. Элемент управления CreateUserWizard можно использовать одним из двух способов:The CreateUserWizard control can be used in one of two ways:

  • Как средство для создания собственной учетной записи пользователя на сайте иAs a means for visitors to create their own user account on the site, and
  • Как средство создания новых учетных записей для администраторовAs a means for administrators to create new accounts

В первом варианте использования посетитель переходит на сайт и заполняет CreateUserWizard, вводя сведения для регистрации на сайте.In the first use case, a visitor comes to the site and fills out the CreateUserWizard, entering their information in order to register on the site. Во втором случае администратор создает новую учетную запись для другого пользователя.In the second case, an administrator creates a new account for another person.

При создании учетной записи администратором другого пользователя может быть полезно разрешить администратору указывать роли, к которым принадлежит новая учетная запись пользователя.When an account is being created by an administrator for some other person, it might be helpful to allow the administrator to specify what roles the new user account belongs to. В учебнике о хранении дополнительных сведений о пользователях мы увидели, как настроить CreateUserWizard, добавив дополнительные WizardSteps.In the Storing Additional User Information tutorial we saw how to customize the CreateUserWizard by adding additional WizardSteps. Давайте посмотрим, как добавить дополнительный шаг к CreateUserWizard, чтобы указать роли нового пользователя.Let's look at how to add an additional step to the CreateUserWizard in order to specify the new user's roles.

Откройте страницу CreateUserWizardWithRoles.aspx и добавьте элемент управления CreateUserWizard с именем RegisterUserWithRoles.Open the CreateUserWizardWithRoles.aspx page and add a CreateUserWizard control named RegisterUserWithRoles. Задайте для свойства ContinueDestinationPageUrl элемента управления значение "~/Дефаулт.аспкс".Set the control's ContinueDestinationPageUrl property to "~/Default.aspx". Так как идея заключается в том, что администратор будет использовать этот элемент управления CreateUserWizard для создания новых учетных записей пользователей, присвойте свойству LoginCreatedUser элемента управления значение false.Because the idea here is that an administrator will be using this CreateUserWizard control to create new user accounts, set the control's LoginCreatedUser property to False. Это LoginCreatedUser свойство указывает, будет ли посетитель автоматически входить в систему в качестве только что созданного пользователя, и по умолчанию имеет значение true.This LoginCreatedUser property specifies whether the visitor is automatically logged on as the just-created user, and it defaults to True. Мы задали значение false, так как при создании новой учетной записи администратор хочет войти в систему как есть.We set it to False because when an administrator creates a new account we want to keep him signed in as himself.

Затем выберите "Добавить/удалить WizardSteps...". из смарт-тега CreateUserWizard и добавьте новый WizardStep, задав для его ID значение SpecifyRolesStep.Next, select the "Add/Remove WizardSteps…" option from the CreateUserWizard's Smart Tag and add a new WizardStep, setting its ID to SpecifyRolesStep. Переместите SpecifyRolesStep WizardStep, чтобы он наступил после шага "зарегистрироваться для новой учетной записи", но перед шагом "завершить".Move the SpecifyRolesStep WizardStep so that it comes after the "Sign Up for Your New Account" step, but before the "Complete" step. Задайте для свойства Title WizardStepзначение "указать роли", свойство StepType для Step, а для свойства AllowReturn — значение false.Set the WizardStep's Title property to "Specify Roles", its StepType property to Step, and its AllowReturn property to False.

добавитьAdd the

Рис. 11. Добавление WizardStep "указание ролей" в CreateUserWizard (щелкните, чтобы просмотреть изображение с полным размером)Figure 11: Add the "Specify Roles" WizardStep to the CreateUserWizard (Click to view full-size image)

После изменения декларативная разметка CreateUserWizard должна выглядеть следующим образом:After this change your CreateUserWizard's declarative markup should look like the following:

<asp:CreateUserWizard ID="RegisterUserWithRoles" runat="server" 
     ContinueDestinationPageUrl="~/Default.aspx" LoginCreatedUser="False"> 

     <WizardSteps> 
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server"> 
          </asp:CreateUserWizardStep> 
          <asp:WizardStep ID="SpecifyRolesStep" runat="server" StepType="Step" 

               Title="Specify Roles" AllowReturn="False"> 
          </asp:WizardStep> 
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server"> 
          </asp:CompleteWizardStep> 
     </WizardSteps> 

</asp:CreateUserWizard>

В WizardStep"указание ролей" добавьте объект CheckBoxList с именем RoleList.In the "Specify Roles" WizardStep, add a CheckBoxList named RoleList. В этом CheckBoxList будут перечислены доступные роли, что позволит пользователю посетить страницу, чтобы проверить, к каким ролям принадлежит только что созданный пользователь.This CheckBoxList will list the available roles, enabling the person visiting the page to check what roles the newly created user belongs to.

Мы оставили две задачи написания кода: сначала необходимо заполнить RoleList CheckBoxList с помощью ролей в системе; Во вторых, необходимо добавить созданного пользователя к выбранным ролям, когда пользователь перейдет с шага "указание ролей" на шаг "завершено".We are left with two coding tasks: first we must populate the RoleList CheckBoxList with the roles in the system; second, we need to add the created user to the selected roles when the user moves from the "Specify Roles" step to the "Complete" step. Мы можем выполнить первую задачу в обработчике событий Page_Load.We can accomplish the first task in the Page_Load event handler. Следующий код программным образом ссылается на флажок RoleList при первом посещении страницы и привязывает к нему роли в системе.The following code programmatically references the RoleList CheckBox on the first visit to the page and binds the roles in the system to it.

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

Приведенный выше код должен показаться знакомым.The above code should look familiar. В учебнике о хранении дополнительных сведений о пользователях мы использовали две инструкции FindControl для ссылки на веб-элемент управления из настраиваемой WizardStep.In the Storing Additional User Information tutorial we used two FindControl statements to reference a Web control from within a custom WizardStep. И код, связывающий роли с CheckBoxList, был взят ранее в этом руководстве.And the code that binds the roles to the CheckBoxList was taken from earlier in this tutorial.

Чтобы выполнить вторую задачу программирования, необходимо знать, когда был выполнен шаг "указание ролей".In order to perform the second programming task we need to know when the "Specify Roles" step has been completed. Вспомним, что CreateUserWizard имеет событие ActiveStepChanged, которое срабатывает при каждом переходе посетителя с одного шага на другой.Recall that the CreateUserWizard has an ActiveStepChanged event, which fires each time the visitor navigates from one step to another. Здесь можно определить, достиг ли пользователь шага «Complete»; в этом случае необходимо добавить пользователя к выбранным ролям.Here we can determine if the user has reached the "Complete" step; if so, we need to add the user to the selected roles.

Создайте обработчик событий для ActiveStepChanged события и добавьте следующий код:Create an event handler for the ActiveStepChanged event and add the following code:

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

Если пользователь только что достиг шага "завершено", обработчик событий перечисляет элементы RoleList CheckBoxList, и только что созданный пользователь назначается выбранным ролям.If the user has just reached the "Completed" step, the event handler enumerates the items of the RoleList CheckBoxList and the just-created user is assigned to the selected roles.

Посетите эту страницу в браузере.Visit this page through a browser. Первым шагом в CreateUserWizard является стандартная операция регистрации для новой учетной записи, которая запрашивает имя пользователя, пароль, адрес электронной почты и другие сведения о новом пользователе.The first step in the CreateUserWizard is the standard "Sign Up for Your New Account" step, which prompts for the new user's username, password, email, and other key information. Введите сведения для создания нового пользователя с именем Ванда.Enter the information to create a new user named Wanda.

создать нового пользователя с именем ВандаCreate a New User Named Wanda

Рис. 12. Создание нового пользователя с именем Ванда (щелкните, чтобы просмотреть изображение с полным размером)Figure 12: Create a New User Named Wanda (Click to view full-size image)

Нажмите кнопку "создать пользователя".Click the "Create User" button. CreateUserWizard внутренне вызывает метод Membership.CreateUser, создает новую учетную запись пользователя, а затем выполняет переход к следующему шагу: "указание ролей".The CreateUserWizard internally calls the Membership.CreateUser method, creating the new user account, and then progresses to the next step, "Specify Roles." Здесь перечислены системные роли.Here the system roles are listed. Установите флажок Супервизоры и нажмите кнопку Далее.Check the Supervisors checkbox and click Next.

сделать Ванда членом роли "руководители"Make Wanda a Member of the Supervisors Role

Рис. 13. сделать Ванда членом роли "руководители" (щелкните, чтобы просмотреть изображение с полным размером)Figure 13: Make Wanda a Member of the Supervisors Role (Click to view full-size image)

Нажатие кнопки "Далее" вызывает обратную передачу и обновляет ActiveStep на шаге "завершено".Clicking Next causes a postback and updates the ActiveStep to the "Complete" step. В обработчике событий ActiveStepChanged недавно созданная учетная запись пользователя назначается роли "руководители".In the ActiveStepChanged event handler, the recently-created user account is assigned to the Supervisors role. Чтобы проверить это, вернитесь на страницу UsersAndRoles.aspx и выберите супервизоров из RoleList DropDownList.To verify this, return to the UsersAndRoles.aspx page and select Supervisors from the RoleList DropDownList. Как показано на рис. 14, Супервизоры теперь состоят из трех пользователей: Брюс, Тито и Ванда.As Figure 14 shows, the Supervisors are now made up of three users: Bruce, Tito, and Wanda.

Брюс, Тито и Ванда являются администраторамиBruce, Tito, and Wanda are All Supervisors

Рис. 14. Брюс, Тито и Ванда — все Супервизоры (щелкните, чтобы просмотреть изображение с полным размером)Figure 14: Bruce, Tito, and Wanda are All Supervisors (Click to view full-size image)

СводкаSummary

Платформа ролей предоставляет методы для получения сведений о ролях конкретного пользователя и методах для определения того, какие пользователи относятся к указанной роли.The Roles framework offers methods for retrieving information about a particular user's roles and methods for determining what users belong to a specified role. Кроме того, существует ряд методов добавления и удаления одного или нескольких пользователей в одной или нескольких ролях.Furthermore, there are a number of methods for adding and removing one or more users to one or more roles. В этом учебнике мы посвящены только двум следующим методам: AddUserToRole и RemoveUserFromRole.In this tutorial we focused on just two of these methods: AddUserToRole and RemoveUserFromRole. Существуют дополнительные варианты, предназначенные для добавления нескольких пользователей в одну роль и для назначения нескольких ролей одному пользователю.There are additional variants designed to add multiple users to a single role and to assign multiple roles to a single user.

Кроме того, в этом учебнике рассматривается расширение элемента управления CreateUserWizard для включения WizardStep для указания вновь создаваемых ролей пользователя.This tutorial also included a look at extending the CreateUserWizard control to include a WizardStep to specify the newly-created user's roles. Такой шаг может помочь администратору упростить процесс создания учетных записей пользователей для новых пользователей.Such a step could help an administrator streamline the process of creating user accounts for new users.

На этом этапе мы рассмотрели создание и удаление ролей, а так же Добавление и удаление пользователей из ролей.At this point we have seen how to create and delete roles and how to add and remove users from roles. Но мы еще не рассмотрим применение авторизации на основе ролей.But we have yet to look at applying role-based authorization. В следующем учебном курсе мы рассмотрим определение правил авторизации URL-адресов для отдельных ролей, а также как ограничить функциональность на уровне страницы на основе ролей пользователя, вошедшего в систему.In the following tutorial we will look at defining URL authorization rules on a role-by-role basis, as well as how to limit page-level functionality based on the currently logged in user's roles.

Поздравляем с программированием!Happy Programming!

Дополнительные материалыFurther Reading

Дополнительные сведения о разделах, обсуждаемых в этом руководстве, см. в следующих ресурсах:For more information on the topics discussed in this tutorial, refer to the following resources:

Об автореAbout the Author

Скотт Митчелл, автор нескольких книг по ASP/ASP. NET и основатель 4GuysFromRolla.com, работал с веб-технологиями Майкрософт с 1998.Scott Mitchell, author of multiple ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Скотт работает как независимый консультант, преподаватель и модуль записи.Scott works as an independent consultant, trainer, and writer. Его последняя книга — Sams обучать себя ASP.NET 2,0 за 24 часа .His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Скотт можно получить по адресу mitchell@4guysfromrolla.com или через свой блог по адресу http://ScottOnWriting.NET.Scott can be reached at mitchell@4guysfromrolla.com or via his blog at http://ScottOnWriting.NET.

Особая благодарность...Special Thanks To…

Эта серия руководств была рассмотрена многими полезными рецензентами.This tutorial series was reviewed by many helpful reviewers. Специалист по интересу для этого руководства был Терезой Мерфи.Lead reviewer for this tutorial was Teresa Murphy. Хотите ознакомиться с моими будущими статьями MSDN?Interested in reviewing my upcoming MSDN articles? Если да, расположите строку в mitchell@4GuysFromRolla.comIf so, drop me a line at mitchell@4GuysFromRolla.com