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

по Скотт Митчелл

Скачать код или скачать PDF

В этом учебнике мы создадим две ASP.NET страницы для помощи в управлении тем, к каким ролям относятся пользователи. На первой странице будут включены средства для просмотра пользователей, принадлежащих к определенной роли, роли, к которым принадлежит конкретный пользователь, и возможность назначать или удалять конкретного пользователя из определенной роли. На второй странице мы дополним элемент управления CreateUserWizard таким образом, чтобы он включал в себя шаг для указания ролей, к которым принадлежит только что созданный пользователь. Это полезно в сценариях, где администратор может создавать учетные записи пользователей.

Введение

В предыдущем учебнике рассматривалась платформа ролей и SqlRoleProvider; Мы увидели, как использовать класс Roles для создания, извлечения и удаления ролей. Помимо создания и удаления ролей, необходимо иметь возможность назначать или удалять пользователей из роли. К сожалению, ASP.NET не поставляется с веб-элементами управления для управления тем, к каким ролям относятся пользователи. Вместо этого для управления этими ассоциациями необходимо создать собственные страницы ASP.NET. Хорошая новость заключается в том, что добавление и удаление пользователей в роли довольно просто. Класс Roles содержит несколько методов для добавления одного или нескольких пользователей к одной или нескольким ролям.

В этом учебнике мы создадим две ASP.NET страницы для помощи в управлении тем, к каким ролям относятся пользователи. На первой странице будут включены средства для просмотра пользователей, принадлежащих к определенной роли, роли, к которым принадлежит конкретный пользователь, и возможность назначать или удалять конкретного пользователя из определенной роли. На второй странице мы дополним элемент управления CreateUserWizard таким образом, чтобы он включал в себя шаг для указания ролей, к которым принадлежит только что созданный пользователь. Это полезно в сценариях, где администратор может создавать учетные записи пользователей.

Приступим.

Вывод списка пользователей, которым принадлежит роль

Первый порядок бизнес-процессов для этого руководства — создание веб-страницы, с которой пользователи могут назначаться ролям. Прежде чем мы соберемся с тем, как назначать роли пользователям, давайте сначала рассмотрим, как определить, к каким ролям относятся пользователи. Существует два способа отобразить эту информацию: "по роли" или "по пользователю". Можно позволить посетителю выбрать роль, а затем показать ее всех пользователей, принадлежащих роли ("по роли"), или предложить посетителю выбрать пользователя и показать ему роли, назначенные этому пользователю (отображение "по пользователю").

Представление "по роли" полезно в тех случаях, когда посетитель хочет узнать набор пользователей, принадлежащих к определенной роли. представление "по пользователю" идеально подходит, когда посетителю нужно узнать, какие роли определенного пользователя. Пусть наша страница включает интерфейсы "по ролям" и "по пользователям".

Начнем с создания интерфейса "по пользователю". Этот интерфейс будет состоять из раскрывающегося списка и списка флажков. Раскрывающийся список будет заполнен набором пользователей в системе; флажки будут перечислять роли. При выборе пользователя в раскрывающемся списке будут проверены роли, к которым принадлежит пользователь. Пользователь, посещающий страницу, может установить или снять флажки, чтобы добавить или удалить выбранного пользователя из соответствующих ролей.

Note

Использование раскрывающегося списка для перечисления учетных записей пользователей не является идеальным выбором для веб-сайтов, где могут быть сотни учетных записей пользователей. Раскрывающийся список предназначен для того, чтобы позволить пользователю выбрать один элемент из относительно короткого списка параметров. Это быстро становится неудобной, так как количество элементов в списке растет. Если вы создаете веб-сайт, который будет потенциально большим числом учетных записей пользователей, можно рассмотреть возможность использования альтернативного пользовательского интерфейса, такого как страничный GridView или интерфейс с фильтрацией, который предлагает посетителю выбрать письмо и только потом показывает пользователей, имена которых начинаются с выбранной буквы.

Шаг 1. Создание пользовательского интерфейса "по пользователю"

Откройте страницу UsersAndRoles.aspx. В верхней части страницы добавьте элемент управления Label с именем ActionStatus и удалите его свойство Text. Мы будем использовать эту метку для предоставления отзывов о выполняемых действиях, отображая такие сообщения, как "пользователь Тито был добавлен в роль" Администраторы ", или" пользователь Цзисунь был удален из роли "руководители". Чтобы эти сообщения были выделены, присвойте свойству CssClass метки значение "важно".

<p align="center"> 

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

Затем добавьте следующее определение класса CSS в таблицу стилей Styles.css:

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

Это определение CSS указывает браузеру отображать метку с помощью большого красного шрифта. На рис. 1 показан этот результат в конструкторе Visual Studio.

свойство CssClass метки получает большой красный шрифт

Рис. 1. свойство CssClass метки приводит к большому красному шрифту (щелкните, чтобы просмотреть изображение с полным размером).

Затем добавьте элемент DropDownList на страницу, задайте для его свойства ID значение UserListи задайте для свойства AutoPostBack значение true. Мы будем использовать этот элемент DropDownList для вывода списка всех пользователей в системе. Это DropDownList будет привязан к коллекции объектов MembershipUser. Так как элементу DropDownList нужно отобразить свойство UserName объекта MembershipUser (и использовать его в качестве значения элементов списка), задайте для свойств DataTextField и DataValueField DropDownList значение UserName.

Под элементом DropDownList добавьте элемент Repeater с именем UsersRoleList. Этот Repeater будет перечислять все роли в системе в виде ряда флажков. Определите ItemTemplate Repeater, используя следующую декларативную разметку:

<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. AutoPostBack свойству CheckBox присвоено значение true, а свойство Text привязано к Container.DataItem. Причина, по которой синтаксис DataBinding является просто Container.DataItem, заключается в том, что платформа ролей возвращает список имен ролей в виде массива строк, и это строковый массив, который мы будем привязать к элементу Repeater. Подробное описание того, почему этот синтаксис используется для вывода содержимого массива, привязанного к веб-элементу управления данными, выходит за рамки данного руководства. Дополнительные сведения об этом важностях см. в статье Привязка скалярного массива к веб-элементу управления данными.

На этом этапе декларативная разметка интерфейса "по пользователю" должна выглядеть следующим образом:

<h3>Manage Roles By User</h3> 

<p> 
     <b>Select a User:</b> 
     <asp:DropDownList ID="UserList" runat="server" AutoPostBack="True" 
          DataTextField="UserName" DataValueField="UserName"> 

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

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

Теперь мы готовы написать код для привязки набора учетных записей пользователей к DropDownList и набору ролей для элемента Repeater. В классе кода программной части страницы добавьте метод с именем BindUsersToUserList и другой с именем BindRolesList, используя следующий код:

private void BindUsersToUserList() 
{ 
     // Get all of the user accounts 
     MembershipUserCollection users = Membership.GetAllUsers(); 
     UserList.DataSource = users; 
     UserList.DataBind(); 
}
 
private void BindRolesToList() 
{ 
     // Get all of the roles 
     string[] roles = Roles.GetAllRoles(); 
     UsersRoleList.DataSource = roles; 
     UsersRoleList.DataBind(); 
}

Метод BindUsersToUserList извлекает все учетные записи пользователей в системе с помощью методаMembership.GetAllUsers. Он возвращает объектMembershipUserCollection, который представляет собой коллекцию экземпляровMembershipUser. Затем эта коллекция привязывается к элементу DropDownList UserList. Экземпляры MembershipUser, описывающего коллекцию, содержат различные свойства, такие как UserName, Email, CreationDateи IsOnline. Чтобы элементу DropDownList отображалось значение свойства UserName, убедитесь UserList, что свойства DataTextField и DataValueField элемента DropDownList установлены в значение UserName.

Note

Метод Membership.GetAllUsers имеет две перегрузки: один, который не принимает входные параметры и возвращает всех пользователей, а второй принимает целочисленные значения для индекса страницы и размера страницы и возвращает только указанное подмножество пользователей. Если в элементе пользовательского интерфейса, доступном для просмотра, отображаются большие объемы учетных записей пользователей, вторая перегрузка может быть использована для более эффективной страницы пользователей, поскольку она возвращает только точное подмножество учетных записей пользователей, а не все из них.

Метод BindRolesToList начинается с вызова методаGetAllRolesкласса Roles, который возвращает массив строк, содержащий роли в системе. Затем этот строковый массив привязывается к элементу Repeater.

Наконец, необходимо вызвать эти два метода при первой загрузке страницы. Добавьте следующий код в обработчик событий Page_Load .

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

Выполнив этот код, уделите время посетить страницу в браузере. экран должен выглядеть примерно так, как показано на рис. 2. Все учетные записи пользователей заполняются в раскрывающемся списке, и под ним каждая роль отображается как флажок. Так как мы устанавливаем свойства AutoPostBack DropDownList и CheckBoxs равными true, изменение выбранного пользователя или проверка или депроверка роли приводит к выполнению обратной передачи. Однако никакие действия не выполняются, так как мы еще не написали код для решения этих действий. Эти задачи будут рассмотрены в следующих двух разделах.

странице отображаются пользователи и роли.

Рис. 2. на странице отображаются пользователи и роли (щелкните, чтобы просмотреть изображение с полным размером)

Проверка ролей, к которым принадлежит выбранный пользователь

При первой загрузке страницы или когда посетитель выбирает нового пользователя из раскрывающегося списка, необходимо обновить флажки UsersRoleList, чтобы флажок запускался только в том случае, если выбранный пользователь принадлежит к этой роли. Для этого создайте метод с именем CheckRolesForSelectedUser со следующим кодом:

private void CheckRolesForSelectedUser() 
{ 
     // Determine what roles the selected user belongs to 
     string selectedUserName = UserList.SelectedValue; 
     string[] selectedUsersRoles = Roles.GetRolesForUser(selectedUserName); 

     // Loop through the Repeater's Items and check or uncheck the checkbox as needed 

     foreach (RepeaterItem ri in UsersRoleList.Items) 
     { 
          // Programmatically reference the CheckBox 
          CheckBox RoleCheckBox = ri.FindControl("RoleCheckBox") as CheckBox; 
          // See if RoleCheckBox.Text is in selectedUsersRoles 
          if (selectedUsersRoles.Contains<string>(RoleCheckBox.Text)) 
               RoleCheckBox.Checked = true; 
          else 
               RoleCheckBox.Checked = false; 
     } 
}

Приведенный выше код начинается с определения того, кто является выбранным пользователем. Затем он использует методGetRolesForUser(userName) класса Roles для возврата набора ролей указанного пользователя в виде массива строк. Далее производится перечисление элементов Repeater и установлен флажок RoleCheckBox каждого элемента в программной ссылке. Флажок проверяется только в том случае, если роль, к которой он соответствует, содержится в selectedUsersRoles массиве строк.

Note

Синтаксис selectedUserRoles.Contains<string>(...) не будет компилироваться, если используется ASP.NET версии 2,0. Метод Contains<string> является частью библиотеки LINQ, которая является новой для ASP.NET 3,5. Если вы все еще используете ASP.NET версии 2,0, используйте вместо этого методArray.IndexOf<string> .

Метод CheckRolesForSelectedUser должен вызываться в двух случаях: при первой загрузке страницы и изменении выбранного индекса DropDownList UserList. Поэтому Вызывайте этот метод из обработчика событий Page_Load (после вызовов BindUsersToUserList и BindRolesToList). Кроме того, создайте обработчик событий для события SelectedIndexChanged DropDownList и вызовите этот метод из него.

protected void Page_Load(object sender, EventArgs e) 
{ 
     if (!Page.IsPostBack) 
     { 

          // Bind the users and roles 
          BindUsersToUserList(); 
          BindRolesToList(); 
          // Check the selected user's roles 
          CheckRolesForSelectedUser(); 
     } 
} 

... 

protected void UserList_SelectedIndexChanged(object sender, EventArgs e) 
{ 
     CheckRolesForSelectedUser(); 
}

С помощью этого кода можно протестировать страницу в браузере. Тем не менее, поскольку на UsersAndRoles.aspxной странице в настоящее время нет возможности назначать пользователям роли, пользователи не имеют ролей. Мы создадим интерфейс для назначения пользователям ролей в течение некоторого времени, так что вы можете взять слово, чтобы этот код работал, и проверить, что он делает это позже, или можно вручную добавить пользователей к ролям, вставив записи в таблицу aspnet_UsersInRoles, чтобы протестировать эту функцию прямо сейчас.

Назначение и удаление пользователей из ролей

Когда посетитель проверяет или снимает флажок в UsersRoleList Repeater, необходимо добавить или удалить выбранного пользователя из соответствующей роли. Свойство AutoPostBack CheckBox в настоящее время имеет значение true, что приводит к тому, что флажок в элементе Repeater будет установлен или снят. Вкратце, нам нужно создать обработчик событий для CheckChanged события CheckBox. Поскольку флажок находится в элементе управления Repeater, необходимо вручную добавить коммуникации обработчика событий. Начните с добавления обработчика событий в класс кода программной части в качестве метода protected, например так:

protected void RoleCheckBox_CheckChanged(object sender, EventArgs e) 
{ 

}

В данный момент мы вернемся к написанию кода для этого обработчика событий. Но сначала выполним обработку событий. Из флажка в ItemTemplateе Repeater добавьте OnCheckedChanged="RoleCheckBox_CheckChanged". Этот синтаксис связывает обработчик событий RoleCheckBox_CheckChanged с событием CheckedChanged RoleCheckBox.

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

Наша последняя задача — завершить обработчик событий RoleCheckBox_CheckChanged. Нам нужно начать с ссылки на элемент управления CheckBox, который вызвал событие, поскольку этот экземпляр CheckBox указывает, какая роль была проверена или снята с помощью свойств Text и Checked. Используя эти сведения вместе с именем пользователя выбранного пользователя, мы добавляем или удаляю пользователя из роли с помощью метода AddUserToRole или RemoveUserFromRoleкласса Roles.

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. Если флажок установлен, выбранный пользователь добавляется к указанной роли, в противном случае он удаляется из роли. В любом случае в метке ActionStatus отображается сообщение с описанием только что выполненного действия.

Уделите время на тестирование этой страницы в браузере. Выберите пользователь Тито, а затем добавьте Тито в роли Администраторы и Супервизоры.

Тито добавлена в роли администраторов и руководителей.

Рис. 3. Тито добавлены в роли администраторов и руководителей (щелкните, чтобы просмотреть изображение с полным размером)

Затем в раскрывающемся списке Выберите User Брюс (пользователь). Обратная передача и флажки Repeater обновляются с помощью CheckRolesForSelectedUser. Так как Брюс еще не принадлежит ни одной роли, два флажка не устанавливаются. Затем добавьте Брюс в роль супервизоров.

Брюс добавлена в роль "руководители"

Рис. 4. Брюс был добавлен в роль "руководители" (щелкните, чтобы просмотреть изображение с полным размером)

Для дальнейшей проверки функциональности метода CheckRolesForSelectedUser выберите пользователя, отличного от Тито или Брюс. Обратите внимание, что флажки автоматически снимаются, отметив, что они не принадлежат ни к одной роли. Вернитесь к Тито. Должны быть установлены флажки администраторы и Супервизоры.

Шаг 2. Создание пользовательского интерфейса "по ролям"

На этом этапе мы завершили работу с интерфейсом "по пользователям" и готовы начать работу с интерфейсом "по ролям". Интерфейс "по ролям" предлагает пользователю выбрать роль из раскрывающегося списка, а затем отображает набор пользователей, принадлежащих к этой роли в элементе управления GridView.

Добавьте еще один элемент управления DropDownList на страницу UsersAndRoles.aspx. Поместите его под элементом управления Repeater, назовите его RoleListи присвойте свойству AutoPostBack значение true. Ниже добавьте GridView и присвойте ему имя RolesUserList. В этом элементе GridView будут перечислены пользователи, принадлежащие к выбранной роли. Задайте для свойства AutoGenerateColumns GridView значение false, добавьте TemplateField в коллекцию Columns сетки и присвойте свойству HeaderText значение "Users". Определите ItemTemplate TemplateField, чтобы на нем отображалось значение выражения привязки данных Container.DataItem в свойстве Text метки с именем UserNameLabel.

После добавления и настройки GridView декларативная разметка интерфейса "по роли" должна выглядеть следующим образом:

<h3>Manage Users By Role</h3> 
<p> 
     <b>Select a Role:</b> 

     <asp:DropDownList ID="RoleList" runat="server" AutoPostBack="true"></asp:DropDownList> 
</p> 
<p>      <asp:GridView ID="RolesUserList" runat="server" AutoGenerateColumns="false" 

          EmptyDataText="No users belong to this role."> 
          <Columns> 
               <asp:TemplateField HeaderText="Users"> 
                    <ItemTemplate> 
                         <asp:Label runat="server" id="UserNameLabel" 
                              Text='<%# Container.DataItem %>'></asp:Label> 

                    </ItemTemplate> 
               </asp:TemplateField> 
          </Columns> 
     </asp:GridView> </p>

Необходимо заполнить RoleList DropDownList набором ролей в системе. Для этого обновите метод BindRolesToList, чтобы привязать массив строк, возвращаемый методом Roles.GetAllRoles, к RolesList DropDownList (а также к 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. На рис. 5 показан конечный результат при просмотре в браузере — раскрывающийся список, заполненный ролями системы.

роли отображаются в DropDownList RoleList

Рис. 5. роли отображаются в RoleList DropDownList (щелкните, чтобы просмотреть изображение с полным размером)

Отображение пользователей, принадлежащих выбранной роли

При первой загрузке страницы или при выборе новой роли из RoleList DropDownList необходимо отобразить список пользователей, принадлежащих к этой роли в GridView. Создайте метод с именем DisplayUsersBelongingToRole, используя следующий код:

private void DisplayUsersBelongingToRole() 
{ 
     // Get the selected role 
     string selectedRoleName = RoleList.SelectedValue; 

     // Get the list of usernames that belong to the role 
     string[] usersBelongingToRole = Roles.GetUsersInRole(selectedRoleName); 

     // Bind the list of users to the GridView 
     RolesUserList.DataSource = usersBelongingToRole; 
     RolesUserList.DataBind(); 
}

Этот метод начинается с получения выбранной роли из RoleList DropDownList. Затем он использует методRoles.GetUsersInRole(roleName) для получения строкового массива имен пользователей, принадлежащих к этой роли. Затем этот массив привязывается к RolesUserList GridView.

Этот метод должен вызываться в двух случаях: при начальной загрузке страницы и при изменении выбранной роли в RoleList DropDownList. Поэтому обновите обработчик событий Page_Load таким образом, чтобы этот метод вызывался после вызова метода CheckRolesForSelectedUser. Затем создайте обработчик событий для события SelectedIndexChanged RoleListи вызовите этот метод из него.

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 должны отображаться пользователи, принадлежащие выбранной роли. Как показано на рис. 6, роль супервизоров состоит из двух членов: Брюс и Тито.

элементе GridView список пользователей, принадлежащих выбранной роли

Рис. 6. список пользователей, принадлежащих выбранной роли (щелкните, чтобы просмотреть изображение с полным размером)

Удаление пользователей из выбранной роли

Добавим RolesUserList GridView, чтобы он включал столбец с кнопками "Удалить". Нажатие кнопки "Удалить" для конкретного пользователя удалит их из этой роли.

Начните с добавления поля кнопки Удалить в GridView. Сделайте это поле наиболее заполненным и измените его свойство DeleteText на "Delete" (по умолчанию) на "Remove" (удалить).

добавить

Рис. 7. Добавление кнопки "Удалить" в GridView (щелкните, чтобы просмотреть изображение с полным размером)

При нажатии кнопки "Удалить" происходит обратная передача, и возникает событие RowDeleting GridView. Необходимо создать обработчик событий для этого события и написать код, который удаляет пользователя из выбранной роли. Создайте обработчик событий, а затем добавьте следующий код:

protected void RolesUserList_RowDeleting(object sender, GridViewDeleteEventArgs e) 
{ 
     // Get the selected role 
     string selectedRoleName = RoleList.SelectedValue; 

     // Reference the UserNameLabel 
     Label UserNameLabel = RolesUserList.Rows[e.RowIndex].FindControl("UserNameLabel") as Label; 

     // Remove the user from the role 
     Roles.RemoveUserFromRole(UserNameLabel.Text, selectedRoleName); 

     // Refresh the GridView 
     DisplayUsersBelongingToRole(); 

     // Display a status message 
     ActionStatus.Text = string.Format("User {0} was removed from role {1}.", UserNameLabel.Text, selectedRoleName); 
}

Код начинается с определения имени выбранной роли. Затем он программно ссылается на элемент управления UserNameLabel из строки, для которой была нажата кнопка "Удалить", чтобы определить имя пользователя, которого нужно удалить. Затем пользователь удаляется из роли с помощью вызова метода Roles.RemoveUserFromRole. После этого RolesUserList GridView обновляется и выводится сообщение с помощью элемента управления Метка ActionStatus.

Note

Перед удалением пользователя из роли для кнопки "Удалить" не требуется никаких подтверждений от пользователя. Я предлагаю добавить некоторый уровень подтверждения пользователя. Одним из самых простых способов подтверждения действия является применение диалогового окна подтверждения на стороне клиента. Дополнительные сведения об этом способе см. в разделе Добавление подтверждения на стороне клиента при удалении.

На рис. 8 показана страница после удаления пользователя Тито из группы «руководители».

увы, Тито больше не является супервизором

Рис. 8. Увы, Тито больше не является супервизором (щелкните, чтобы просмотреть изображение с полным размером)

Добавление новых пользователей к выбранной роли

Вместе с удалением пользователей из выбранной роли посетитель этой страницы также должен иметь возможность добавить пользователя к выбранной роли. Лучший интерфейс для добавления пользователя в выбранную роль зависит от количества учетных записей пользователей, которые вы ожидаете использовать. Если ваш веб-сайт будет размещать всего несколько десятков учетных записей пользователей, можно использовать DropDownList. Если могут быть тысячи учетных записей пользователей, необходимо включить пользовательский интерфейс, позволяющий посетителям пролистывать учетные записи, выполнять поиск конкретной учетной записи или фильтровать учетные записи пользователей каким-либо другим способом.

Для этой страницы мы будем использовать очень простой интерфейс, который работает независимо от количества учетных записей пользователей в системе. А именно, мы будем использовать текстовое поле, предлагающее посетителю ввести имя пользователя, которого пользователь хочет добавить в выбранную роль. Если пользователь с таким именем не существует или пользователь уже является членом роли, в ActionStatus метка будет отображаться сообщение. Но если пользователь существует и не является членом роли, мы добавим его к роли и обновляем сетку.

Добавьте текстовое поле и кнопку под элементом GridView. Задайте для текстового поля ID значение UserNameToAddToRole и задайте для свойств ID и Text кнопки значение AddUserToRoleButton и "добавить пользователя в роль" соответственно.

<p> 
     <b>UserName:</b> 
     <asp:TextBox ID="UserNameToAddToRole" runat="server"></asp:TextBox> 
     <br /> 
     <asp:Button ID="AddUserToRoleButton" runat="server" Text="Add User to Role" /> 

</p>

Затем создайте обработчик событий Click для AddUserToRoleButton и добавьте следующий код:

protected 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 выполняет различные проверки. Это гарантирует, что посетитель указал имя пользователя в текстовом поле UserNameToAddToRole, что пользователь уже существует в системе и не принадлежит выбранной роли. Если какая-либо из этих проверок завершается сбоем, в ActionStatus отображается соответствующее сообщение, а обработчик событий завершает работу. Если все проверки пройдены, пользователь добавляется к роли с помощью метода Roles.AddUserToRole. После этого удаляется свойство Text текстового поля, GridView обновляется, а ActionStatus метка отображает сообщение о том, что указанный пользователь успешно добавлен в выбранную роль.

Note

Чтобы убедиться, что указанный пользователь еще не принадлежит выбранной роли, мы используем методRoles.IsUserInRole(userName, roleName), который возвращает логическое значение, указывающее, является ли имя пользователя членом roleName. Мы будем использовать этот метод еще раз в следующем руководстве , когда мы рассмотрим авторизацию на основе ролей.

Откройте страницу в браузере и выберите роль супервизоров в RoleList DropDownList. Попробуйте ввести недопустимое имя пользователя. должно отобразиться сообщение о том, что пользователь не существует в системе.

нельзя добавить несуществующего пользователя к роли

Рис. 9. невозможно добавить несуществующего пользователя к роли (щелкните, чтобы просмотреть изображение с полным размером)

Теперь попробуйте добавить допустимого пользователя. Снова добавьте Тито в роль супервизоров.

Тито еще раз является супервизором!

Рис. 10. Тито снова является супервизором! (Щелкните, чтобы просмотреть изображение с полным размером)

Шаг 3. Перекрестное обновление интерфейсов "по пользователям" и "по ролям"

Страница UsersAndRoles.aspx предлагает два отдельных интерфейса для управления пользователями и ролями. В настоящее время эти два интерфейса работают независимо друг от друга, поэтому изменение, внесенное в одном интерфейсе, не будет немедленно отражено в другом. Например, представьте, что посетитель страницы выбирает роль супервизоров из RoleList DropDownList, где в качестве членов перечисляются Брюс и Тито. Затем посетитель выбирает UserList Тито в элементе DropDownList, который проверяет флажки "Администраторы" и "Супервизоры" в UsersRoleList Repeater. Если затем посетитель отменяет роль супервизора от повторителя, Тито удаляется из роли супервизоров, но это изменение не отражается в интерфейсе Role. GridView по-прежнему будет показывать Тито как член роли "руководители".

Чтобы исправить это, необходимо обновить GridView при проверке или снятии роли с UsersRoleList Repeater. Аналогичным образом, необходимо обновлять Repeater каждый раз, когда пользователь удаляется или добавляется к роли из интерфейса "по роли".

Элемент Repeater в интерфейсе "по пользователю" обновляется путем вызова метода CheckRolesForSelectedUser. Интерфейс "по роли" можно изменить в обработчике событий RowDeleting RolesUserList GridView и обработчике событий Click кнопки AddUserToRoleButton. Поэтому необходимо вызвать метод CheckRolesForSelectedUser из каждого из этих методов.

protected void RolesUserList_RowDeleting(object sender, GridViewDeleteEventArgs e) 
{ 
     ... Code removed for brevity ... 

     // Refresh the "by user" interface 
     CheckRolesForSelectedUser(); 
} 

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


     // Refresh the "by user" interface 
     CheckRolesForSelectedUser(); 
}

Аналогично, элемент управления GridView в интерфейсе "по роли" обновляется путем вызова метода DisplayUsersBelongingToRole, а интерфейс "по пользователю" изменяется с помощью обработчика событий RoleCheckBox_CheckChanged. Поэтому нам нужно вызвать метод DisplayUsersBelongingToRole из этого обработчика событий.

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

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

В результате этих незначительных изменений кода интерфейсы "по пользователям" и "по ролям" теперь правильно перекрестно обновляются. Чтобы проверить это, перейдите на страницу браузера и выберите Тито и Супервизоры в UserList и RoleList элементов управления DropDownList соответственно. Обратите внимание, что при снятии флажка роли Супервизоры для Тито из Repeater в интерфейсе "по пользователям" Тито автоматически удаляется из GridView в интерфейсе "по ролям". При добавлении Тито к роли супервизоров из интерфейса "по роли" автоматически проверяется флажок "руководители" в интерфейсе "по пользователям".

Шаг 4. Настройка CreateUserWizard для включения шага "указание ролей"

В учебнике Создание учетных записей пользователей мы увидели, как использовать веб-элемент управления CreateUserWizard, чтобы предоставить интерфейс для создания новой учетной записи пользователя. Элемент управления CreateUserWizard можно использовать одним из двух способов:

  • Как средство для создания собственной учетной записи пользователя на сайте и
  • Как средство создания новых учетных записей для администраторов

В первом варианте использования посетитель переходит на сайт и заполняет CreateUserWizard, вводя сведения для регистрации на сайте. Во втором случае администратор создает новую учетную запись для другого пользователя.

При создании учетной записи администратором другого пользователя может быть полезно разрешить администратору указывать роли, к которым принадлежит новая учетная запись пользователя. В учебнике о хранении дополнительных сведений о пользователях мы увидели, как настроить CreateUserWizard, добавив дополнительные WizardSteps. Давайте посмотрим, как добавить дополнительный шаг к CreateUserWizard, чтобы указать роли нового пользователя.

Откройте страницу CreateUserWizardWithRoles.aspx и добавьте элемент управления CreateUserWizard с именем RegisterUserWithRoles. Задайте для свойства ContinueDestinationPageUrl элемента управления значение "~/Дефаулт.аспкс". Так как идея заключается в том, что администратор будет использовать этот элемент управления CreateUserWizard для создания новых учетных записей пользователей, присвойте свойству LoginCreatedUser элемента управления значение false. Это LoginCreatedUser свойство указывает, будет ли посетитель автоматически входить в систему в качестве только что созданного пользователя, и по умолчанию имеет значение true. Мы задали значение false, так как при создании новой учетной записи администратор хочет войти в систему как есть.

Затем выберите "Добавить/удалить WizardSteps...". из смарт-тега CreateUserWizard и добавьте новый WizardStep, задав для его ID значение SpecifyRolesStep. Переместите SpecifyRolesStep WizardStep, чтобы он наступил после шага "зарегистрироваться для новой учетной записи", но перед шагом "завершить". Задайте для свойства Title WizardStepзначение "указать роли", свойство StepType для Step, а для свойства AllowReturn — значение false.

добавить

Рис. 11. Добавление WizardStep "указание ролей" в CreateUserWizard (щелкните, чтобы просмотреть изображение с полным размером)

После изменения декларативная разметка CreateUserWizard должна выглядеть следующим образом:

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

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

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

</asp:CreateUserWizard>

В WizardStep"указание ролей" добавьте объект CheckBoxList с именем RoleList. В этом CheckBoxList будут перечислены доступные роли, что позволит пользователю посетить страницу, чтобы проверить, к каким ролям принадлежит только что созданный пользователь.

Мы оставили две задачи написания кода: сначала необходимо заполнить RoleList CheckBoxList с помощью ролей в системе; Во вторых, необходимо добавить созданного пользователя к выбранным ролям, когда пользователь перейдет с шага "указание ролей" на шаг "завершено". Мы можем выполнить первую задачу в обработчике событий Page_Load. Следующий код программным образом ссылается на флажок RoleList при первом посещении страницы и привязывает к нему роли в системе.

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

Приведенный выше код должен показаться знакомым. В учебнике о хранении дополнительных сведений о пользователях мы использовали две инструкции FindControl для ссылки на веб-элемент управления из настраиваемой WizardStep. И код, связывающий роли с CheckBoxList, был взят ранее в этом руководстве.

Чтобы выполнить вторую задачу программирования, необходимо знать, когда был выполнен шаг "указание ролей". Вспомним, что CreateUserWizard имеет событие ActiveStepChanged, которое срабатывает при каждом переходе посетителя с одного шага на другой. Здесь можно определить, достиг ли пользователь шага «Complete»; в этом случае необходимо добавить пользователя к выбранным ролям.

Создайте обработчик событий для ActiveStepChanged события и добавьте следующий код:

protected void RegisterUserWithRoles_ActiveStepChanged(object sender, EventArgs e) 
{ 
     // Have we JUST reached the Complete step? 
     if (RegisterUserWithRoles.ActiveStep.Title == "Complete") 
     { 
          // Reference the SpecifyRolesStep WizardStep 
          WizardStep SpecifyRolesStep = RegisterUserWithRoles.FindControl("SpecifyRolesStep") as WizardStep; 

          // Reference the RoleList CheckBoxList 
          CheckBoxList RoleList = SpecifyRolesStep.FindControl("RoleList") as CheckBoxList; 

          // Add the checked roles to the just-added user 
          foreach (ListItem li in RoleList.Items) 

          { 
               if (li.Selected) 
                    Roles.AddUserToRole(RegisterUserWithRoles.UserName, li.Text); 
          } 
     } 
}

Если пользователь только что достиг шага "завершено", обработчик событий перечисляет элементы RoleList CheckBoxList, и только что созданный пользователь назначается выбранным ролям.

Посетите эту страницу в браузере. Первым шагом в CreateUserWizard является стандартная операция регистрации для новой учетной записи, которая запрашивает имя пользователя, пароль, адрес электронной почты и другие сведения о новом пользователе. Введите сведения для создания нового пользователя с именем Ванда.

создать нового пользователя с именем Ванда

Рис. 12. Создание нового пользователя с именем Ванда (щелкните, чтобы просмотреть изображение с полным размером)

Нажмите кнопку "создать пользователя". CreateUserWizard внутренне вызывает метод Membership.CreateUser, создает новую учетную запись пользователя, а затем выполняет переход к следующему шагу: "указание ролей". Здесь перечислены системные роли. Установите флажок Супервизоры и нажмите кнопку Далее.

сделать Ванда членом роли "руководители"

Рис. 13. сделать Ванда членом роли "руководители" (щелкните, чтобы просмотреть изображение с полным размером)

Нажатие кнопки "Далее" вызывает обратную передачу и обновляет ActiveStep на шаге "завершено". В обработчике событий ActiveStepChanged недавно созданная учетная запись пользователя назначается роли "руководители". Чтобы проверить это, вернитесь на страницу UsersAndRoles.aspx и выберите супервизоров из RoleList DropDownList. Как показано на рис. 14, Супервизоры теперь состоят из трех пользователей: Брюс, Тито и Ванда.

Брюс, Тито и Ванда являются администраторами

Рис. 14. Брюс, Тито и Ванда — все Супервизоры (щелкните, чтобы просмотреть изображение с полным размером)

Сводка

Платформа ролей предоставляет методы для получения сведений о ролях конкретного пользователя и методах для определения того, какие пользователи относятся к указанной роли. Кроме того, существует ряд методов добавления и удаления одного или нескольких пользователей в одной или нескольких ролях. В этом учебнике мы посвящены только двум следующим методам: AddUserToRole и RemoveUserFromRole. Существуют дополнительные варианты, предназначенные для добавления нескольких пользователей в одну роль и для назначения нескольких ролей одному пользователю.

Кроме того, в этом учебнике рассматривается расширение элемента управления CreateUserWizard для включения WizardStep для указания вновь создаваемых ролей пользователя. Такой шаг может помочь администратору упростить процесс создания учетных записей пользователей для новых пользователей.

На этом этапе мы рассмотрели создание и удаление ролей, а так же Добавление и удаление пользователей из ролей. Но мы еще не рассмотрим применение авторизации на основе ролей. В следующем учебном курсе мы рассмотрим определение правил авторизации URL-адресов для отдельных ролей, а также как ограничить функциональность на уровне страницы на основе ролей пользователя, вошедшего в систему.

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

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

Дополнительные сведения о разделах, обсуждаемых в этом руководстве, см. в следующих ресурсах:

Об авторе

Скотт Митчелл, автор нескольких книг по ASP/ASP. NET и основатель 4GuysFromRolla.com, работал с веб-технологиями Майкрософт с 1998. Скотт работает как независимый консультант, преподаватель и модуль записи. Его последняя книга — Sams обучать себя ASP.NET 2,0 за 24 часа . Скотт можно получить по адресу mitchell@4guysfromrolla.com или через свой блог по адресу http://ScottOnWriting.NET.

Особая благодарность...

Эта серия руководств была рассмотрена многими полезными рецензентами. Специалист по интересу для этого руководства был Терезой Мерфи. Хотите ознакомиться с моими будущими статьями MSDN? Если да, расположите строку в mitchell@4GuysFromRolla.com