Создание учетных записей пользователей (C#)

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

Примечание.

С тех пор как эта статья была написана, поставщики членства ASP.NET были заменены ASP.NET Identity. Мы настоятельно рекомендуем обновить приложения для использования платформы ASP.NET Identity , а не поставщиков членства, которые были представлены в то время, когда эта статья была написана. ASP.NET Identity имеет ряд преимуществ по сравнению с системой членства ASP.NET, в том числе:

  • Повышенная производительность
  • Улучшенная расширяемость и возможность тестирования
  • Поддержка OAuth, OpenID Connect и двухфакторной проверки подлинности
  • Поддержка индентификации на основе утверждений
  • Улучшение взаимодействия с ASP.Net Core

Скачивание кода или скачивание PDF

В этом руководстве мы рассмотрим использование платформы членства (через SqlMembershipProvider) для создания учетных записей пользователей. Мы посмотрим, как создавать новых пользователей в программной среде и с помощью встроенного элемента управления CreateUserWizard в ASP.NET.

Введение

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

Помимо обучения созданию новых учетных записей пользователей, нам также потребуется обновить демонстрационный веб-сайт, который мы сначала создали в Обзор проверки подлинности форм, а затем усовершенствовали в Конфигурация проверки подлинности форм и расширенные темы. Наше демонстрационное веб-приложение имеет страницу входа, которая проверяет учетные данные пользователей на основе жестко закодированных пар имени пользователя и пароля. Кроме того, Global.asax включает код, который создает пользовательские объекты IPrincipal и IIdentity для аутентифицированных пользователей. Мы обновим страницу входа, чтобы проверить учетные данные пользователей в рамках платформы членства и удалить пользовательскую логику субъекта и удостоверения.

Приступим.

Контрольный список аутентификации с использованием форм и управления членством

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

  1. Включите проверку подлинности на основе форм. Как обсуждалось в Обзор аутентификации на основе форм, аутентификация на основе форм включается путем редактирования Web.config и задания атрибута mode элемента <authentication> в Forms. При включенной проверке подлинности форм каждый входящий запрос проверяется для запроса проверки подлинности форм, который, если он присутствует, идентифицирует запрашивающего.
  2. Добавьте схему служб приложений в соответствующую базу данных. При использовании SqlMembershipProvider необходимо установить схему служб приложений в базу данных. Обычно эта схема добавляется в ту же базу данных, которая содержит модель данных приложения. Руководство по созданию схемы членства в SQL Server с помощью aspnet_regsql.exe этого средства.
  3. Настройте параметры веб-приложения, чтобы ссылаться на базу данных на шаге 2. В руководстве по созданию схемы членства в SQL Server показано два способа настройки веб-приложения, чтобы SqlMembershipProvider использовать базу данных, выбранную на шаге 2: путем изменения LocalSqlServer имени строки подключения; или добавления нового зарегистрированного поставщика в список поставщиков фреймворка членства и настройки этого нового поставщика для работы с базой данных, использующей информацию с шага 2.

При создании веб-приложения, использующего проверку подлинности на основе форм, необходимо выполнить эти три действия, прежде чем использовать SqlMembershipProviderMembership класс или веб-элементы управления ASP.NET Login. Так как мы уже выполнили эти действия в предыдущих руководствах, мы готовы начать работу с платформой членства!

Шаг 1. Добавление новых страниц ASP.NET

В этом руководстве и следующих трех мы рассмотрим различные функции и возможности, связанные с членством. Нам потребуется ряд страниц ASP.NET для реализации тем, рассмотренных в этих руководствах. Создадим эти страницы, а затем файл карты сайта (Web.sitemap).

Начните с создания новой папки в проекте с именем Membership. Затем добавьте пять новых ASP.NET страниц в Membership папку, связав каждую страницу с главной страницей Site.master . Назовите страницы:

  • CreatingUserAccounts.aspx
  • UserBasedAuthorization.aspx
  • EnhancedCreateUserWizard.aspx
  • AdditionalUserInfo.aspx
  • Guestbook.aspx

На этом этапе Обозреватель решений проекта должен выглядеть примерно так, как на снимке экрана, показанном на рис. 1.

В папку членства добавлены пять новых страниц.

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

Каждая страница, на данном этапе, должна иметь два элемента управления содержимым, по одному для каждого заполнителя содержимого основной страницы: MainContent и LoginContent.

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"

Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent"
Runat="Server">
</asp:Content>

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

Однако для этих пяти страниц мы хотим показать разметку эталонной страницы по умолчанию для LoginContent ContentPlaceHolder. Поэтому удалите декларативную разметку для элемента управления содержимым Content2. После этого каждая из пяти страниц должна содержать только один элемент управления содержимым.

Шаг 2. Создание карты сайта

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

Эти две задачи — определение карты сайта и реализация навигационного пользовательского интерфейса на основе карты сайта — это легко сделать благодаря платформе карты сайта и веб-элементам управления навигации, добавленным в ASP.NET версии 2.0. Платформа "Карта сайта" позволяет разработчику определить карту сайта, а затем получить к ней доступ через программный API ( SiteMap класс). Встроенные веб-элементы управления навигации включают элемент управления Menu, элемент управления TreeView и элемент управления SiteMapPath.

Как и платформы членства и ролей, платформа карты сайта создается на вершине модели поставщика. Задание класса поставщика карты сайта заключается в создании структуры в памяти, используемой SiteMap классом из постоянного хранилища данных, например XML-файла или таблицы базы данных. Платформа .NET Framework поставляется с поставщиком карты сайта по умолчанию, который считывает данные карты сайта из XML-файла (XmlSiteMapProvider), и это поставщик, который мы будем использовать в этом руководстве. Для некоторых альтернативных реализаций поставщика карт сайта см. раздел "Дополнительные чтения" в конце этого руководства.

Поставщик карты сайта по умолчанию ожидает правильно отформатированный XML-файл с именем Web.sitemap, который должен находиться в корневом каталоге. Так как мы используем этот поставщик по умолчанию, необходимо добавить такой файл и определить структуру карты сайта в соответствующем формате XML. Чтобы добавить файл, щелкните правой кнопкой мыши имя проекта в Обозреватель решений и выберите "Добавить новый элемент". В диалоговом окне выберите добавить файл типа "Карта сайта".Web.sitemap

Добавление файла с именем Web.sitemap в корневой каталог проекта

Рис. 2. Добавление файла с именем Web.sitemap в корневой каталог проекта (щелкните, чтобы просмотреть изображение полного размера)

Xml-файл карты сайта определяет структуру веб-сайта в виде иерархии. Эта иерархическая связь моделирована в XML-файле с помощью происхождения <siteMapNode> элементов. Необходимо, чтобы Web.sitemap начинался с родительского узла <siteMap>, который имеет ровно один дочерний узел <siteMapNode>. Этот элемент верхнего уровня <siteMapNode> представляет корень иерархии и может иметь произвольное количество узлов-потомков. Каждый элемент <siteMapNode> должен включать атрибут title и может при необходимости включать атрибуты url и description, среди прочих; каждый непустой атрибут url должен быть уникальным.

Введите следующий XML-код в Web.sitemap файл:

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
     <siteMapNode url="~/Default.aspx" title="Home">
          <siteMapNode title="Membership">
               <siteMapNode url="~/Membership/CreatingUserAccounts.aspx" title="Creating User Accounts" />

               <siteMapNode url="~/Membership/UserBasedAuthorization.aspx" title="User-Based Authorization" />
               <siteMapNode url="~/Membership/Guestbook.aspx" title="Storing Additional User Information" />
          </siteMapNode>

     </siteMapNode>
</siteMap>

Приведенная выше разметка карты сайта определяет иерархию, показанную на рис. 3.

Схема сайта представляет иерархическую структуру навигации

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

Шаг 3. Обновление главной страницы для включения пользовательского интерфейса навигации

ASP.NET включает ряд веб-элементов управления, связанных с навигацией, для разработки пользовательского интерфейса. К ним относятся элементы управления Menu, TreeView и SiteMapPath. Элементы управления Menu и TreeView отображают структуру карты сайта в меню или дереве соответственно, в то время как SiteMapPath отображает "хлебные крошки", показывающие текущий узел, который просматривается, а также его предков. Данные карты сайта можно привязать к другим элементам управления данными с помощью SiteMapDataSource и получить к ним доступ программным способом с использованием класса SiteMap.

Так как тщательное обсуждение платформы карты сайта и элементов управления навигацией выходит за рамки этой серии учебников, а не тратить время на создание собственного пользовательского интерфейса навигации давайте вместо этого заимствуем тот, который используется в моей работе с данными в ASP.NET 2.0 серии учебников, который использует элемент управления Repeater для отображения двух глубоких маркированных списков ссылок навигации, как показано на рис. 4.

Чтобы создать этот интерфейс, добавьте следующую декларативную разметку Site.master в левый столбец главной страницы, где текст "TODO: Меню будет идти здесь..." в настоящее время находится.

<ul>
     <li>

          <asp:HyperLink runat="server" ID="lnkHome" NavigateUrl="~/Default.aspx">Home</asp:HyperLink>
     </li>
     <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">

          <ItemTemplate>
               <li>
                    <asp:HyperLink ID="lnkMenuItem" runat="server" 
                         NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>

                    <asp:Repeater ID="submenu" runat="server" DataSource="<%#
                         ((SiteMapNode) Container.DataItem).ChildNodes %>">
                         <HeaderTemplate>
                              <ul>
                         </HeaderTemplate>
                         <ItemTemplate>

                              <li>
                                   <asp:HyperLink ID="lnkMenuItem" runat="server" NavigateUrl='<%#
                                        Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>

                              </li>
                         </ItemTemplate>
                         <FooterTemplate>
                              </ul>
                         </FooterTemplate>
                    </asp:Repeater>
               </li>
          </ItemTemplate>
     </asp:Repeater>

</ul>
    
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" />

Приведенная выше разметка привязывает элемент управления Repeater с именем menu к источнику данных SiteMapDataSource, который возвращает иерархию карты сайта, определенную в Web.sitemap. Так как свойство элемента управления SiteMapDataSource установлено в значение False, оно начинает возвращать иерархию карты сайта, начиная с дочерних элементов узла "Главная". Повторитель отображает каждый из этих узлов (в настоящий момент только "Состав") в элементе <li>. Другой, внутренний повторитель затем отображает дочерние элементы текущего узла в вложенном неупорядоченном списке.

На рисунке 4 показан визуализированный результат разметки с структурой карты сайта, созданной на шаге 2. Повторитель отрисовывает ванильную разметку неупорядоченного списка; каскадные правила таблицы стилей, определенные в Styles.css, отвечают за эстетически приятный макет. Более подробное описание работы приведенной выше разметки см. в руководстве по эталонным страницам и навигации по сайтам.

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

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

Добавление навигации по хлебным крошкам

Помимо списка ссылок в левом столбце, давайте также добавим отображение путей навигации (breadcrumb) на каждой странице. Панель навигации — это элемент пользовательского интерфейса навигации, который быстро показывает пользователям текущее положение в иерархии сайта. Элемент управления SiteMapPath использует платформу "Карта сайта" для определения расположения текущей страницы на карте сайта, а затем отображает панель навигации на основе этих сведений.

В частности, добавьте <span> элемент в элемент заголовка <div> главной страницы и задайте для атрибута нового <span> элемента class значение "breadcrumb". (Класс Styles.css содержит правило для класса "breadcrumb".) Затем добавьте SiteMapPath в этот новый <span> элемент.

<div id="header">
     <span class="title">User Account Tutorials</span><br />
     <span class="breadcrumb">
          <asp:SiteMapPath ID="SiteMapPath1" runat="server">

          </asp:SiteMapPath>
     </span>
</div>

На рисунке 5 показаны выходные данные SiteMapPath при посещении ~/Membership/CreatingUserAccounts.aspx.

Хлебные крошки отображают текущую страницу и ее предков в карте сайта

Рис. 5. Навигационная цепочка отображает текущую страницу и её иерархию на карте сайта (нажмите, чтобы просмотреть изображение в полном размере)

Шаг 4. Удаление пользовательской логики принципала и идентичности

Настраиваемые субъекты и объекты удостоверений могут быть связаны с аутентифицированным пользователем. Мы выполнили это путем создания обработчика Global.asax событий для события приложения PostAuthenticateRequest , который запускается после FormsAuthenticationModule проверки подлинности пользователя. В этом обработчике событий мы заменили объекты GenericPrincipal и FormsIdentity, добавленные с помощью FormsAuthenticationModule, объектами CustomPrincipal и CustomIdentity, которые мы создали в том учебном пособии.

Хотя пользовательские объекты принципала и идентификации полезны в определенных сценариях, в большинстве случаев объектов GenericPrincipal и FormsIdentity достаточно. Следовательно, я думаю, что стоит вернуться к поведению по умолчанию. Внесите это изменение, удалив или закомментируя PostAuthenticateRequest обработчик событий или полностью удалив Global.asax файл.

Шаг 5. Программное создание нового пользователя

Чтобы создать новую учетную запись пользователя с помощью Membership framework, используйте метод класса MembershipCreateUser. Этот метод имеет входные параметры для полей имени пользователя, пароля и других связанных с пользователем полей. При вызове функция делегирует создание новой учетной записи пользователя настроенному поставщику членства, а затем возвращает MembershipUser объект, представляющий только что созданную учетную запись пользователя.

Метод CreateUser имеет четыре перегрузки, каждый из которых принимает другое количество входных параметров:

Эти четыре перегрузки отличаются по объему собираемой информации. Например, для первой перегрузки требуется только имя пользователя и пароль для новой учетной записи пользователя, а второй также требует адреса электронной почты пользователя.

Эти перегрузки существуют, так как сведения, необходимые для создания учетной записи пользователя, зависят от параметров конфигурации поставщика членства. В руководстве по созданию схемы членства в SQL Server мы рассмотрели параметры конфигурации поставщика членства в Web.config. Таблица 2 содержит полный список параметров конфигурации.

Один из таких параметров конфигурации поставщика членства, который влияет на то, какие CreateUser перегрузки могут использоваться, — это requiresQuestionAndAnswer параметр. Если requiresQuestionAndAnswer задано значение true (по умолчанию), то при создании новой учетной записи пользователя необходимо указать вопрос безопасности и ответ. Эти сведения позже используются, если пользователю нужно сбросить или изменить пароль. Они видят контрольный вопрос и должны ввести правильный ответ, чтобы изменить или сбросить пароль. Следовательно, если requiresQuestionAndAnswer установлено на true, то вызов любой из первых двух перегрузок CreateUser приводит к исключению, поскольку отсутствуют вопрос безопасности и ответ. Так как наше приложение в настоящее время настроено на требование безопасности и ответа, нам потребуется использовать одну из последних двух перегрузк при программном создании пользователя.

Чтобы проиллюстрировать использование CreateUser метода, давайте создадим пользовательский интерфейс, в котором мы запрашиваем пользователю имя, пароль, электронную почту и ответ на предварительно определенный вопрос безопасности. CreatingUserAccounts.aspx Откройте страницу в папке Membership и добавьте следующие веб-элементы управления в элемент управления Content:

  • TextBox с именем Username
  • Имя TextBox Password, свойство которого TextMode задано в значение Password
  • TextBox с именем Email
  • Метка с именем SecurityQuestion, у которой свойство Text очищено.
  • TextBox с именем SecurityAnswer
  • Кнопка с именем CreateAccountButton , свойство Text которого имеет значение Create the User Account (Создать учетную запись пользователя)
  • Элемент управления с именем CreateAccountResults Label, у которого свойство Text очищено

На этом этапе экран должен выглядеть примерно так, как на снимке экрана, показанном на рис. 6.

Добавление различных веб-элементов управления на страницу CreatingUserAccounts.aspx

Рис. 6. Добавление различных веб-элементов управления на CreatingUserAccounts.aspx страницу (щелкните, чтобы просмотреть изображение полного размера)

Метка SecurityQuestion и SecurityAnswer текстовое поле предназначены для отображения предварительно определенного вопроса безопасности и сбора ответа пользователя. Обратите внимание, что вопрос безопасности и ответ хранятся для каждого пользователя отдельно, поэтому каждый пользователь может определить свой собственный вопрос безопасности. Однако в этом примере я решил использовать универсальный вопрос безопасности, а именно: "Какой ваш любимый цвет?"

Чтобы реализовать этот предварительно определенный вопрос безопасности, добавьте константу в класс кодовой части страницы с именем passwordQuestion, назначив его вопрос безопасности. Затем в обработчике Page_Load событий назначьте эту константу свойству SecurityQuestion Label Text :

const string passwordQuestion = "What is your favorite color";
    
protected void Page_Load(object sender, EventArgs e)
{
     if (!Page.IsPostBack)
          SecurityQuestion.Text = passwordQuestion;
}

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

protected void CreateAccountButton_Click(object sender, EventArgs e)
{
     MembershipCreateStatus createStatus;
     MembershipUser newUser = Membership.CreateUser(Username.Text, Password.Text, Email.Text, passwordQuestion, SecurityAnswer.Text, true, out createStatus);
     switch (createStatus)
     {
          case MembershipCreateStatus.Success:
               CreateAccountResults.Text = "The user account was successfully created!";
               break;
          case MembershipCreateStatus.DuplicateUserName:
               CreateAccountResults.Text = "There already exists a user with this username.";
               break;

          case MembershipCreateStatus.DuplicateEmail:
               CreateAccountResults.Text = "There already exists a user with this email address.";
               break;
          case MembershipCreateStatus.InvalidEmail:
               CreateAccountResults.Text = "There email address you provided in invalid.";
               break;
          case MembershipCreateStatus.InvalidAnswer:
               CreateAccountResults.Text = "There security answer was invalid.";
               break;
          case MembershipCreateStatus.InvalidPassword:
               CreateAccountResults.Text = "The password you provided is invalid. It must be seven characters long and have at least one non-alphanumeric character.";

               break;
          default:
               CreateAccountResults.Text = "There was an unknown error; the user account was NOT created.";
               break;
     }
}

Обработчик Click событий начинается с определения переменной с именем createStatus типа MembershipCreateStatus. MembershipCreateStatus — это перечисление, указывающее состояние CreateUser операции. Например, если учетная запись пользователя создана успешно, результирующий MembershipCreateStatus экземпляр будет иметь значение Success; с другой стороны, если операция завершается ошибкой, так как уже существует пользователь с тем же именем пользователя, он будет иметь значение DuplicateUserName. В используемой CreateUser перегрузке необходимо передать MembershipCreateStatus экземпляр в метод в качестве out параметра. Этот параметр имеет соответствующее значение в методе CreateUser , и мы можем проверить его значение после вызова метода, чтобы определить, была ли учетная запись пользователя успешно создана.

После вызова CreateUser и передачи createStatus используется оператор switch для вывода соответствующего сообщения в зависимости от значения, назначенного в createStatus. На рисунке 7 показаны выходные данные при успешном создании нового пользователя. На рисунках 8 и 9 отображаются выходные данные, когда учетная запись пользователя не создана. На рисунке 8 посетитель ввел пятибуквенный пароль, который не соответствует требованиям к надежности паролей, указанным в параметрах конфигурации поставщика членства. На рис. 9 посетитель пытается создать учетную запись пользователя с существующим именем пользователя (созданным на рис. 7).

Новая учетная запись пользователя успешно создана

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

Учетная запись пользователя не создана, так как предоставленный пароль слишком слаб

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

Учетная запись пользователя не создана, так как имя пользователя уже используется

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

Примечание.

Возможно, вам интересно, как определить успешность или сбой при использовании одной из первых двух перегрузок метода CreateUser, у которых нет параметра типа MembershipCreateStatus. Эти первые две перегрузки вызывают MembershipCreateUserException исключение в случае сбоя, включающегоStatusCodeсвойство типаMembershipCreateStatus.

После создания нескольких учетных записей пользователей убедитесь, что учетные записи были созданы путем перечисления содержимого aspnet_Users и aspnet_Membership таблиц в SecurityTutorials.mdf базе данных. Как показано на рисунке 10, я добавил двух пользователей через страницу: Тито и Брюс.

В Хранилище пользователей членства есть два пользователя: Тито и Брюс

Рис. 10. В хранилище учетных записей есть два пользователя: Tito и Брюс (нажмите, чтобы просмотреть изображение полного размера)

Хотя хранилище пользователей членства теперь включает в себя сведения об учетной записи Брюса и Тито, мы еще не реализовали функциональные возможности, позволяющие Брюс или Тито войти на сайт. На данный момент Login.aspx проверяет учетные данные пользователя по жестко закодированному набору пар имени пользователя и пароля. Он не проверяет предоставленные учетные данные с помощью фреймворка Membership. Пока придется довольствоваться просмотром новых учетных записей пользователей в таблицах aspnet_Users и aspnet_Membership. В следующем руководстве по валидации учетных данных пользователя в системе членства мы обновим страницу входа для проверки в хранилище пользователей системы членства.

Примечание.

Если вы не видите никаких пользователей в SecurityTutorials.mdf базе данных, это может быть связано с тем, что веб-приложение использует поставщик служб участников по умолчанию, AspNetSqlMembershipProvider, который использует ASPNETDB.mdf базу данных в качестве своего хранилища пользователей. Чтобы определить, является ли это проблемой, нажмите кнопку "Обновить" в обозревателе решений. Если имя ASPNETDB.mdf базы данных было добавлено в App_Data папку, это проблема. Вернитесь к шагу 4 руководства по созданию схемы членства в SQL Server , чтобы узнать, как правильно настроить поставщика членства.

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

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

Если новые учетные записи пользователей создаются только с помощью типичной веб-страницы создания учетной записи, вряд ли потребуется написать код, использующий CreateUser метод, так как элемент управления CreateUserWizard, скорее всего, соответствует вашим потребностям. Однако этот CreateUser метод удобно использовать в сценариях, где требуется высоко настраиваемый интерфейс пользователя "Создание учетной записи" или при необходимости программного создания учетных записей пользователей с помощью альтернативного интерфейса. Например, у вас может быть страница, которая позволяет пользователю отправлять XML-файл, содержащий сведения о пользователе из другого приложения. Страница может разобрать содержимое загруженного XML-файла и создать новую учетную запись для каждого пользователя, представленного в XML CreateUser, путем вызова метода.

Шаг 6. Создание пользователя с помощью элемента управления CreateUserWizard

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

Как и многие другие веб-элементы управления, связанные с именем входа, можно использовать CreateUserWizard без написания одной строки кода. Он интуитивно предоставляет пользовательский интерфейс на основе параметров конфигурации поставщика членства и вызывает метод Membership класса CreateUser после того, как пользователь вводит необходимые сведения и нажимает кнопку "Создать пользователя". Элемент управления CreateUserWizard обладает высокой степенью настраиваемости. Существует множество событий, которые выполняются на различных этапах процесса создания учетной записи. При необходимости можно создать обработчики событий для внедрения пользовательской логики в рабочий процесс создания учетной записи. Кроме того, внешний вид CreateUserWizard очень гибкий. Существует ряд свойств, определяющих внешний вид интерфейса по умолчанию; При необходимости элемент управления можно преобразовать в шаблон или добавить дополнительные действия регистрации пользователя.

Начнем с использования интерфейса и поведения элемента управления CreateUserWizard по умолчанию. Затем мы рассмотрим, как настроить внешний вид с помощью свойств и событий элемента управления.

Изучение интерфейса и поведения CreateUserWizard по умолчанию

Вернитесь на CreatingUserAccounts.aspx страницу в Membership папке, перейдите в режим конструктора или разделения, а затем добавьте элемент управления CreateUserWizard в верхнюю часть страницы. Элемент управления CreateUserWizard находится в разделе "Элементы управления для входа" панели инструментов. После добавления элемента управления задайте для свойства значение IDRegisterUser. Как показано на снимке экрана на рисунке 11, CreateUserWizard отображает интерфейс с текстовыми полями для имени пользователя нового пользователя, пароля, адреса электронной почты и вопроса безопасности и ответа.

Элемент управления CreateUserWizard отображает универсальный интерфейс создания пользователя

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

Давайте уделим минуту, чтобы сравнить интерфейс пользователя по умолчанию, созданный с помощью элемента управления CreateUserWizard, с интерфейсом, который мы создали на шаге 5. Для начала элемент управления CreateUserWizard позволяет посетителю указать как вопрос безопасности, так и ответ, тогда как наш созданный вручную интерфейс использовал предварительно определенный вопрос безопасности. Интерфейс элемента управления CreateUserWizard также включает элементы управления проверкой, в то время как мы еще не реализовали проверку в полях формы нашего интерфейса. И интерфейс управления CreateUserWizard содержит текстовое поле "Подтверждение пароля" (наряду с CompareValidator, чтобы убедиться, что текст, введенный в текстовое поле "Пароль" и "Сравнить пароль", равны).

Интересно, что элемент управления CreateUserWizard обращается к параметрам конфигурации поставщика членства при отрисовке пользовательского интерфейса. Например, текстовые поля с вопросами безопасности и ответами отображаются только в том случае, если requiresQuestionAndAnswer задано значение True. Аналогичным образом, CreateUserWizard автоматически добавляет элемент управления RegularExpressionValidator, чтобы убедиться, что требования к надежности паролей выполнены, и задает его свойства ErrorMessage и ValidationExpression, основываясь на параметрах конфигурации minRequiredPasswordLength, minRequiredNonalphanumericCharacters и passwordStrengthRegularExpression.

Элемент управления CreateUserWizard, судя по его названию, является производным от элемента управления Wizard. Элементы управления мастера предназначены для создания интерфейса для выполнения многоэтапных задач. Элемент управления "Мастер" может иметь произвольное количество WizardStepsэлементов управления, каждое из которых является шаблоном, определяющим элементы управления HTML и веб-элементы управления для этого шага. Изначально элемент управления "Мастер" отображает первый WizardStep, а также элементы управления навигацией, которые позволяют пользователю переходить с одного шага на следующий или возвращаться к предыдущим шагам.

Как показано на декларативной разметке на рисунке 11, интерфейс элемента управления CreateUserWizard по умолчанию включает два WizardSteps:.

  • CreateUserWizardStep — отображает интерфейс для сбора сведений о создании новой учетной записи пользователя. Это шаг, показанный на рис. 11.
  • CompleteWizardStep — отображает сообщение, указывающее, что учетная запись успешно создана.

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

Давайте увидим элемент управления CreateUserWizard в действии. Посетите страницу CreatingUserAccounts.aspx через браузер. Начните с ввода некоторых недопустимых значений в интерфейс CreateUserWizard. Попробуйте ввести пароль, который не соответствует требованиям к надежности пароля, или оставить текстовое поле "Имя пользователя" пустым. В createUserWizard отобразится соответствующее сообщение об ошибке. На рисунке 12 показаны выходные данные при попытке создать пользователя с недостаточно строгим паролем.

CreateUserWizard автоматически внедряет элементы управления проверкой

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

Затем введите соответствующие значения в createUserWizard и нажмите кнопку "Создать пользователя". Предполагая, что обязательные поля были введены, а сила пароля достаточна, createUserWizard создаст новую учетную запись пользователя через платформу членства, а затем отобразит CompleteWizardStepинтерфейс (см. рис. 13). За кулисами CreateUserWizard вызывает метод Membership.CreateUser, так же, как мы сделали на шаге 5.

Новая учетная запись пользователя успешно создана

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

Примечание.

Как показано на рисунке 13, CompleteWizardStepинтерфейс включает кнопку "Продолжить". На данном этапе при нажатии на него просто отправляются данные на сервер, и посетитель остается на той же странице. В разделе "Настройка внешнего вида и поведения CreateUserWizard через его свойства" мы рассмотрим, как можно настроить, чтобы эта кнопка перенаправляла посетителя на Default.aspx (или другую страницу).

После создания учетной записи пользователя вернитесь в Visual Studio и просмотрите таблицы aspnet_Users и aspnet_Membership, как показано на рис. 10, чтобы убедиться, что учетная запись была успешно создана.

Настройка поведения и внешнего вида CreateUserWizard с помощью его свойств

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

Практически весь текст, отображаемый в пользовательском интерфейсе элемента управления CreateUserWizard по умолчанию, можно настроить с помощью его множества свойств. Например, метки "Имя пользователя", "Пароль", "Подтверждение пароля", "Электронная почта", "Вопрос безопасности" и "Ответ на безопасность", отображаемые слева от текстовых полей, можно настроить соответствующим образом.UserNameLabelTextPasswordLabelTextConfirmPasswordLabelTextEmailLabelTextQuestionLabelTextAnswerLabelText Аналогичным образом существуют свойства для указания текста кнопок "Создать пользователя" и "Продолжить" в CreateUserWizardStep и CompleteWizardStep, а также, если эти кнопки представлены как Кнопки, LinkButtons или ImageButtons.

Цвета, границы, шрифты и другие визуальные элементы настраиваются с помощью нескольких свойств стиля. Сам элемент управления CreateUserWizard имеет общие свойства стиля веб-элемента управления — , BackColorBorderStyle, CssClassFontи т. д., а также есть ряд свойств стиля для определения внешнего вида для определенных разделов интерфейса CreateUserWizard. TextBoxStyle Например, свойство определяет стили текстовых ящиков в полеCreateUserWizardStep, а TitleTextStyle свойство определяет стиль заголовка ("Регистрация для новой учетной записи").

Помимо свойств, связанных с внешним видом, есть ряд свойств, влияющих на поведение элемента управления CreateUserWizard. Если DisplayCancelButton задано значение True, отображается кнопка "Отмена" рядом с кнопкой "Создать пользователя" (значение по умолчанию — False). Если вы отображаете кнопку "Отмена", обязательно задайте CancelDestinationPageUrl свойство, указывающее страницу, на которую отправляется пользователь после нажатия кнопки "Отмена". Как отмечалось в предыдущем разделе, кнопка "Продолжить" в интерфейсе CompleteWizardStep вызывает постбэк, но оставляет посетителя на той же странице. Чтобы отправить посетителя на другую страницу после нажатия кнопки "Продолжить", просто укажите URL-адрес в свойствеContinueDestinationPageUrl.

Давайте обновим элемент управления RegisterUser CreateUserWizard, чтобы отобразить кнопку "Отмена" и перенаправить посетителя на Default.aspx при нажатии кнопок "Отмена" или "Продолжить". Для этого установите для свойства DisplayCancelButton значение True, а для свойств CancelDestinationPageUrl и ContinueDestinationPageUrl значение "~/Default.aspx". На рисунке 14 показан обновленный файл CreateUserWizard при просмотре через браузер.

CreateUserWizardStep включает кнопку

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

Когда посетитель вводит имя пользователя, пароль, адрес электронной почты и ответ и нажимает кнопку "Создать пользователя", создается новая учетная запись пользователя, и посетитель вошел в систему как только что созданный пользователь. Предположим, что пользователь, посещающий страницу, создает новую учетную запись для себя, это, скорее всего, нужное поведение. Однако может потребоваться разрешить администраторам добавлять новые учетные записи пользователей. При этом будет создана учетная запись пользователя, но администратор останется вошедшим в систему в качестве администратора (а не в качестве вновь созданной учетной записи). Это поведение можно изменить, используя логическое свойство LoginCreatedUser.

Учетные записи пользователей в платформе членства содержат утвержденный флаг; пользователи, которые не утверждены, не могут войти на сайт. По умолчанию только что созданная учетная запись помечается как утвержденная, что позволяет пользователю немедленно войти на сайт. Однако возможно, чтобы новые учетные записи пользователей были помечены как неутвержденные. Возможно, администратор должен вручную утвердить новых пользователей, прежде чем они смогут войти в систему; или, возможно, вы хотите убедиться, что адрес электронной почты, введенный при регистрации, действителен, прежде чем разрешить пользователю войти в систему. Независимо от этого, вы можете сделать только что созданную учетную запись пользователя помеченной как неодобренной, установив значение свойства DisableCreatedUser элемента управления CreateUserWizard в True (значение по умолчанию — False).

Другие свойства, связанные с поведением, включают AutoGeneratePassword и MailDefinition. AutoGeneratePassword Если для свойства задано значение True, CreateUserWizardStep не отображаются текстовые поля "Пароль" и "Подтверждение пароля"; вместо этого пароль только что созданного пользователя создается автоматически, используя методGeneratePassword класса Membership. Метод GeneratePassword создает пароль указанной длины и достаточное количество небуквенно-цифровых символов для удовлетворения настроенных требований к надежности паролей.

Свойство MailDefinition полезно, если вы хотите отправить электронное письмо на адрес электронной почты, указанный во время процесса создания учетной записи. Свойство MailDefinition содержит ряд вложенных свойств для определения сведений о созданном сообщении электронной почты. Эти вложенные функции включают такие параметры, как Subject, Priority, IsBodyHtml, From, CCи BodyFileName. Свойство BodyFileName указывает на текстовый или HTML-файл, содержащий текст сообщения электронной почты. Текст поддерживает два предварительно определенных заполнителя: <%UserName%> и <%Password%>. Эти заполнители, если они присутствуют в BodyFileName файле, будут заменены именем и паролем только что созданного пользователя.

Примечание.

Свойство CreateUserWizard элемента управления MailDefinition просто указывает сведения о сообщении электронной почты, которое отправляется при создании новой учетной записи. Он не содержит никаких сведений о том, как на самом деле отправляется сообщение электронной почты (то есть используется ли SMTP-сервер или каталог удаления почты, любая информация о проверке подлинности и т. д.). Эти детали низкого уровня должны быть определены в <system.net> разделе Web.config. Дополнительные сведения об этих параметрах конфигурации и отправке электронной почты из ASP.NET 2.0 см. в разделе Часто задаваемые вопросы на SystemNetMail.com и в моей статье Отправка электронной почты в ASP.NET 2.0.

Расширение поведения CreateUserWizard с помощью обработчиков событий

Элемент управления CreateUserWizard вызывает ряд событий во время рабочего процесса. Например, после ввода имени пользователя, пароля и других соответствующих сведений посетитель нажимает кнопку "Создать пользователя", элемент управления CreateUserWizard вызывает его CreatingUser событие. Если во время создания возникает проблема, CreateUserError событие инициализируется; однако, если пользователь успешно создан, CreatedUser событие вызывается. Существуют дополнительные события элемента управления CreateUserWizard, которые вызываются, однако это три наиболее актуальные.

В некоторых сценариях может потребоваться подключиться к рабочему процессу CreateUserWizard, который можно сделать, создав обработчик событий для соответствующего события. Чтобы проиллюстрировать это, давайте расширим RegisterUser элемент управления CreateUserWizard, чтобы включить пользовательскую проверку имени пользователя и пароля. В частности, давайте расширим возможности CreateUserWizard, чтобы имена пользователей не содержали начальные или конечные пробелы, а имя пользователя не может отображаться в любом месте пароля. Короче говоря, мы хотим запретить пользователю создавать имя пользователя, например "Скотт", или иметь сочетание имени пользователя и пароля, например "Скотт" и "Скотт.1234".

Для этого мы создадим обработчик событий для события, CreatingUser чтобы выполнить дополнительные проверки. Если предоставленные данные недопустимы, нам нужно отменить процесс создания. Кроме того, необходимо добавить на страницу веб-элемент управления Label, чтобы отобразить сообщение, объясняющее, что имя пользователя или пароль недопустимы. Сначала добавьте элемент управления Label под элементом управления CreateUserWizard, задав его свойство ID значением InvalidUserNameOrPasswordMessage, а его свойство ForeColor значением Red. Очистите его свойство Text и задайте для его свойств EnableViewState и Visible значение False.

<asp:Label runat="server" id="InvalidUserNameOrPasswordMessage"
     Visible="false" ForeColor="Red" EnableViewState="false">

</asp:Label>

Затем создайте обработчик событий для события элемента управления CreatingUser CreateUserWizard. Чтобы создать обработчик событий, выберите элемент управления в конструкторе и перейдите к окно свойств. Щелкните значок молнии и дважды щелкните соответствующее событие, чтобы создать обработчик событий.

Добавьте следующий код в обработчик событий CreatingUser .

protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e)
{
     string trimmedUserName = RegisterUser.UserName.Trim();
     if (RegisterUser.UserName.Length != trimmedUserName.Length)
     {
          // Show the error message
          InvalidUserNameOrPasswordMessage.Text = "The username cannot contain leading or trailing spaces.";
          InvalidUserNameOrPasswordMessage.Visible = true;

          // Cancel the create user workflow
          e.Cancel = true;
     }
     else
     {
          // Username is valid, make sure that the password does not contain the username

          if (RegisterUser.Password.IndexOf(RegisterUser.UserName, StringComparison.OrdinalIgnoreCase) >= 0)
          {
               // Show the error message
               InvalidUserNameOrPasswordMessage.Text = "The username may not appear anywhere in the password.";
               InvalidUserNameOrPasswordMessage.Visible = true;
               // Cancel the create user workflow
               e.Cancel = true;
          }
     }
}

Обратите внимание, что имя пользователя и пароль, введенные в элемент управления CreateUserWizard, доступны в его UserName и Password свойствах соответственно. Эти свойства используются в приведенном выше обработчике событий, чтобы определить, содержит ли указанное имя пользователя начальные или конечные пробелы, а также указывает, найдено ли имя пользователя в пароле. Если выполняется одно из этих условий, в метке отображается InvalidUserNameOrPasswordMessage сообщение об ошибке, а для свойства обработчика e.Cancel событий задано значение true. Если e.Cancel установлено в true, функция CreateUserWizard прерывает рабочий процесс, эффективно отменяя процесс создания учетной записи пользователя.

На рисунке 15 показан снимок экрана CreatingUserAccounts.aspx, когда пользователь вводит имя пользователя с начальными пробелами.

Имена пользователей с начальными или конечными пробелами не разрешены

Рис. 15. Имена пользователей с начальными или конечными пробелами не разрешены (щелкните, чтобы просмотреть изображение полного размера)

Примечание.

В руководстве по хранению дополнительной информации о пользователе мы увидим пример использования события CreatedUser элемента управления CreateUserWizard.

Итоги

Membership Метод класса CreateUser создает новую учетную запись пользователя в платформе членства. Это осуществляется путем делегирования вызова настроенному провайдеру членства. В случае с SqlMembershipProvider методом метод CreateUser добавляет запись в таблицы базы данных aspnet_Users и aspnet_Membership.

Хотя новые учетные записи пользователей можно создавать программным способом (как мы видели на шаге 5), более быстрый и простой подход — использовать элемент управления CreateUserWizard. Этот элемент управления отображает многофакторный пользовательский интерфейс для сбора сведений о пользователях и создания нового пользователя в платформе членства. Под капотом этот элемент управления использует тот же метод Membership.CreateUser, что и в шаге 5, но он создает пользовательский интерфейс, элементы проверки, а также принимает ответные меры на ошибки при создании учетной записи пользователя, не написав при этом ни строчки кода.

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

Счастливое программирование!

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

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

Об авторе

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

Особое спасибо...

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