Сохранение дополнительных сведений о пользователе (VB)
Примечание
С момента написания этой статьи поставщики членства ASP.NET были заменены ASP.NET Identity. Мы настоятельно рекомендуем обновить приложения для использования платформы ASP.NET Identity , а не поставщиков членства, которые были представлены на момент написания этой статьи. ASP.NET Identity имеет ряд преимуществ по сравнению с системой членства ASP.NET, в том числе :
- более высокая производительность;
- Улучшенная расширяемость и тестируемость
- Поддержка OAuth, OpenID Connect и двухфакторной проверки подлинности
- Поддержка удостоверений на основе утверждений
- Улучшенное взаимодействие с ASP.Net Core
Скачать код или скачать PDF-файл
В этом руководстве мы ответим на этот вопрос, создав очень зачаточные приложения гостевой книги. При этом мы рассмотрим различные варианты моделирования сведений о пользователях в базе данных, а затем узнаем, как связать эти данные с учетными записями пользователей, созданными платформой членства.
Введение
ASP. Платформа членства NET предлагает гибкий интерфейс для управления пользователями. API членства включает методы проверки учетных данных, получения сведений о вошедшего в систему пользователя, создания новой учетной записи пользователя и удаления учетной записи пользователя. Каждая учетная запись пользователя на платформе членства содержит только свойства, необходимые для проверки учетных данных и выполнения важных задач, связанных с учетной записью пользователя. Об этом свидетельствуют методы и свойства MembershipUser
класса , который моделирует учетную запись пользователя на платформе членства. Этот класс имеет свойства, такие как UserName
, Email
и IsLockedOut
, и методы, такие как GetPassword
и UnlockUser
.
Часто приложениям требуется хранить дополнительные сведения о пользователях, не включенные в платформу членства. Например, интернет-магазину может потребоваться разрешить каждому пользователю хранить адреса доставки и выставления счетов, платежные сведения, предпочтения доставки и контактный номер телефона. Кроме того, каждый заказ в системе связан с определенной учетной записью пользователя.
Класс MembershipUser
не включает такие свойства, как PhoneNumber
или DeliveryPreferences
.PastOrders
Как же отслеживать сведения о пользователе, необходимые приложению, и интегрировать их с платформой членства? В этом руководстве мы ответим на этот вопрос, создав очень зачаточные приложения гостевой книги. При этом мы рассмотрим различные варианты моделирования сведений о пользователях в базе данных, а затем узнаем, как связать эти данные с учетными записями пользователей, созданными платформой членства. Приступим к работе!
Шаг 1. Создание модели данных приложения Гостевой книги
Существует множество методов, которые можно использовать для сбора сведений о пользователях в базе данных и их связывания с учетными записями пользователей, созданными платформой членства. Чтобы проиллюстрировать эти методы, необходимо дополнить учебное веб-приложение, чтобы оно записывало какие-то данные, связанные с пользователями. (В настоящее время модель данных приложения содержит только таблицы служб приложений, необходимые для SqlMembershipProvider
.)
Давайте создадим очень простое приложение гостевой книги, в котором пользователь, прошедший проверку подлинности, может оставить комментарий. В дополнение к хранению комментариев гостевой книги, давайте разрешим каждому пользователю хранить свой родной город, домашнюю страницу и подпись. Если это указано, то родной город, домашняя страница и подпись пользователя будут отображаться в каждом сообщении, оставленном в гостевой книге.
GuestbookComments
Добавление таблицы
Чтобы записать комментарии гостевой книги, необходимо создать таблицу базы данных с именем GuestbookComments
, которая содержит такие столбцы, как CommentId
, Subject
, Body
и CommentDate
. Нам также нужно, чтобы каждая запись в GuestbookComments
таблице ссылались на пользователя, который оставил комментарий.
Чтобы добавить эту таблицу в базу данных, перейдите к Обозреватель базы данных в Visual Studio и изучите SecurityTutorials
базу данных. Щелкните правой кнопкой мыши папку Таблицы и выберите команду Добавить новую таблицу. Откроется интерфейс, позволяющий определить столбцы для новой таблицы.
Рис. 1. Добавление новой таблицы в SecurityTutorials
базу данных (щелкните для просмотра полноразмерного изображения)
Затем определите GuestbookComments
столбцы . Начните с добавления столбца с именем CommentId
типа uniqueidentifier
. Этот столбец будет уникальным образом идентифицировать каждый комментарий в гостевой книге, поэтому запретить NULL
s и пометить его как первичный ключ таблицы. Вместо того чтобы указывать значение для CommentId
поля в каждом INSERT
, можно указать, что новое uniqueidentifier
значение должно быть автоматически создано для этого поля в , INSERT
задав для столбца значение NEWID()
по умолчанию . После добавления этого первого поля, помечая его как первичный ключ и задав его значение по умолчанию, ваш экран должен выглядеть так же, как на снимке экрана, показанном на рисунке 2.
Рис. 2. Добавление основного столбца с именем CommentId
(щелкните для просмотра полноразмерного изображения)
Затем добавьте столбец с именем Subject
типа nvarchar(50)
и столбец с именем Body
типа nvarchar(MAX)
, запретив NULL
s в обоих столбцах. После этого добавьте столбец с именем CommentDate
типа datetime
. Запретить NULL
и задать CommentDate
для столбца значение getdate()
по умолчанию .
Остается только добавить столбец, который связывает учетную запись пользователя с каждым комментарием гостевой книги. Одним из вариантов является добавление столбца с именем UserName
типа nvarchar(256)
. Это подходящий вариант при использовании поставщика членства, отличного от SqlMembershipProvider
. Но при использовании SqlMembershipProvider
, как это описано в этой серии руководств, UserName
столбец в aspnet_Users
таблице не гарантируется, что он будет уникальным. Первичный aspnet_Users
ключ таблицы имеет UserId
тип uniqueidentifier
. Поэтому для GuestbookComments
таблицы требуется столбец с именем UserId
типа uniqueidentifier
(запретить NULL
значения). Добавьте этот столбец.
Примечание
Как мы обсуждали в учебнике Создание схемы членства в SQL Server, платформа членства предназначена для предоставления нескольким веб-приложениям с разными учетными записями пользователей совместно использовать одно и то же хранилище пользователей. Это делается путем секционирования учетных записей пользователей по разным приложениям. И хотя каждое имя пользователя гарантированно будет уникальным в пределах приложения, одно и то же имя пользователя может использоваться в разных приложениях, использующих одно и то же хранилище пользователей. В таблице есть составное UNIQUE
ограничение aspnet_Users
для UserName
полей и ApplicationId
, но не для одного UserName
только поля. Следовательно, в таблице aspnet_Users может быть две (или более) записи с одинаковым UserName
значением. Однако UNIQUE
есть ограничение на aspnet_Users
поле таблицы UserId
(так как оно является первичным ключом). Ограничение UNIQUE
важно, так как без него невозможно установить ограничение внешнего ключа между GuestbookComments
таблицами и aspnet_Users
.
После добавления столбца UserId
сохраните таблицу, щелкнув значок Сохранить на панели инструментов. Назовите новую таблицу GuestbookComments
.
У нас есть последняя проблема с таблицей GuestbookComments
: необходимо создать ограничение внешнего ключа между столбцом GuestbookComments.UserId
и столбцом aspnet_Users.UserId
. Для этого щелкните значок Связь на панели инструментов, чтобы открыть диалоговое окно Связи внешних ключей. (Кроме того, можно запустить это диалоговое окно, перейдя в меню Таблица Designer и выбрав Связи.)
Нажмите кнопку Добавить в левом нижнем углу диалогового окна Связи внешних ключей. Это добавит новое ограничение внешнего ключа, хотя нам по-прежнему нужно определить таблицы, участвующие в связи.
Рис. 3. Использование диалогового окна "Связи внешних ключей" для управления ограничениями внешнего ключа таблицы (щелкните для просмотра полноразмерного изображения)
Затем щелкните значок с многоточием в строке "Спецификации таблиц и столбцов" справа. Откроется диалоговое окно Таблицы и столбцы, в котором можно указать таблицу и столбец первичного GuestbookComments
ключа, а также столбец внешнего ключа из таблицы. В частности, выберите aspnet_Users
и UserId
в качестве таблицы и столбца первичного GuestbookComments
ключа, а UserId
в таблице — столбец внешнего ключа (см. рис. 4). Определив таблицы и столбцы первичного и внешнего ключей, нажмите кнопку ОК, чтобы вернуться в диалоговое окно Связи внешних ключей.
Рис. 4. Установка ограничения внешнего ключа между aspnet_Users
таблицами и GuesbookComments
(щелкните для просмотра полноразмерного изображения)
На этом этапе установлено ограничение внешнего ключа. Наличие этого ограничения обеспечивает реляционную целостность между двумя таблицами, гарантируя, что запись гостевой книги никогда не будет ссылаться на несуществующую учетную запись пользователя. По умолчанию ограничение внешнего ключа запрещает удаление родительской записи при наличии соответствующих дочерних записей. То есть, если пользователь делает один или несколько комментариев гостевой книги, а затем мы попытаемся удалить ее учетную запись, удаление завершится ошибкой, если его комментарии гостевой книги не будут удалены первым.
Ограничения внешнего ключа можно настроить для автоматического удаления связанных дочерних записей при удалении родительской записи. Другими словами, мы можем настроить это ограничение внешнего ключа, чтобы записи гостевой книги пользователя автоматически удалялись при удалении учетной записи пользователя. Для этого разверните раздел "Спецификация INSERT and UPDATE" и задайте для свойства "Удалить правило" значение Каскад.
Рис. 5. Настройка ограничения внешнего ключа для каскадных удалений (щелкните для просмотра полноразмерного изображения)
Чтобы сохранить ограничение внешнего ключа, нажмите кнопку Закрыть, чтобы выйти из связи внешнего ключа. Затем щелкните значок Сохранить на панели инструментов, чтобы сохранить таблицу и эту связь.
Хранение домашней страницы, домашней страницы и подписи пользователя
В GuestbookComments
таблице показано, как хранить информацию, которая использует отношение "один ко многим" с учетными записями пользователей. Так как у каждой учетной записи пользователя может быть произвольное количество связанных комментариев, эта связь смоделирована путем создания таблицы для хранения набора комментариев, включающего столбец, который связывает каждый комментарий с конкретным пользователем. При использовании SqlMembershipProvider
эту связь лучше всего установить, создав столбец с именем UserId
типа uniqueidentifier
и ограничение внешнего ключа между этим столбцом и aspnet_Users.UserId
.
Теперь нам нужно связать три столбца с каждой учетной записью пользователя, чтобы сохранить его родной город, домашнюю страницу и подпись, которые будут отображаться в комментариях к гостевой книге. Это можно сделать разными способами.
Добавление новых столбцов в
aspnet_Users
Илиaspnet_Membership
Таблицы. Я бы не рекомендовал этот подход, так как он изменяет схему, используемую .SqlMembershipProvider
Это решение может вернуться, чтобы преследовать вас вниз по дороге. Например, что делать, если в будущей версии ASP.NET используется другаяSqlMembershipProvider
схема. Корпорация Майкрософт может включить средство для переноса данных ASP.NET 2.0SqlMembershipProvider
в новую схему, но если вы изменили схему ASP.NET 2.0SqlMembershipProvider
, такое преобразование может оказаться невозможным.Используйте ASP. Платформа профилей NET, определяющая свойство профиля для домашнего города, домашней страницы и подписи. ASP.NET включает в себя платформу профилей, предназначенную для хранения дополнительных пользовательских данных. Как и платформа членства, платформа профилей строится на основе модели поставщика. Платформа .NET Framework поставляется с
SqlProfileProvider
, который хранит данные профиля в базе данных SQL Server. В нашей базе данных уже есть таблица, используемаяSqlProfileProvider
(aspnet_Profile
), так как она была добавлена при добавлении служб приложений в учебнике Создание схемы членства в SQL Server.
Main преимущество платформы профилей заключается в том, что она позволяет разработчикам определять свойства профиля вWeb.config
— не нужно писать код для сериализации данных профиля в базовое хранилище данных и из него. Короче говоря, очень легко определить набор свойств профиля и работать с ними в коде. Тем не менее, система профилей оставляет желать лучшего, когда дело доходит до управления версиями, поэтому если у вас есть приложение, в котором вы ожидаете добавить новые пользовательские свойства позже или существующие свойства, которые будут удалены или изменены, то платформа профилей может оказаться не лучшим вариантом. Кроме того,SqlProfileProvider
свойства профиля хранятся с высокой денормализацией, что делает практически невозможным выполнение запросов непосредственно к данным профиля (например, сколько пользователей имеет родной город Нью-йорк).
Дополнительные сведения о платформе профилей см. в разделе "Дополнительные сведения" в конце этого руководства.Добавьте эти три столбца в новую таблицу в базе данных и установите связь "один к одному" между этой таблицей и
aspnet_Users
. Этот подход включает в себя немного больше работы, чем с платформой профилей, но обеспечивает максимальную гибкость в моделировать дополнительные свойства пользователя в базе данных. Это параметр, который мы будем использовать в этом руководстве.
Мы создадим новую таблицу с именем UserProfiles
, чтобы сохранить родной город, домашнюю страницу и подпись для каждого пользователя. Щелкните правой кнопкой мыши папку Таблицы в окне база данных Обозреватель и выберите команду создать новую таблицу. Присвойте первому столбцу UserId
uniqueidentifier
имя и задайте для его типа значение . Запретить NULL
значения и пометить столбец как первичный ключ. Затем добавьте столбцы с именами: HomeTown
типа nvarchar(50)
; HomepageUrl
типа nvarchar(100)
; и сигнатура типа nvarchar(500)
. Каждый из этих трех столбцов может принимать NULL
значение.
Рис. 6. Создание UserProfiles
таблицы (щелкните для просмотра полноразмерного изображения)
Сохраните таблицу и назовите ее UserProfiles
. Наконец, установите ограничение внешнего ключа между полем UserProfiles
UserId
таблицы и полем aspnet_Users.UserId
. Как и в случае с ограничением внешнего ключа между GuestbookComments
таблицами и aspnet_Users
, удаляйте это ограничение каскадом. UserId
Так как поле в UserProfiles
является первичным ключом, это гарантирует, что в UserProfiles
таблице будет не более одной записи для каждой учетной записи пользователя. Этот тип связи называется "один к одному".
Теперь, когда у нас есть модель данных, мы готовы использовать ее. В шагах 2 и 3 мы рассмотрим, как вошедший в систему пользователь может просматривать и изменять сведения о родном городе, домашней странице и подписи. На шаге 4 мы создадим интерфейс для пользователей, прошедших проверку подлинности, для отправки новых комментариев в гостевой книге и просмотра существующих.
Шаг 2. Отображение домашней страницы, домашней страницы и подписи пользователя
Существует множество способов, с помощью которых пользователь, выполнивший вход в систему, может просматривать и изменять свой родной город, домашнюю страницу и сведения о подписях. Мы могли бы вручную создать пользовательский интерфейс с элементами управления TextBox и Label или использовать один из веб-элементов управления данными, например Элемент управления DetailsView. Чтобы выполнить базу данных SELECT
и UPDATE
инструкции, можно написать ADO.NET код в классе кода программной части страницы или, в качестве альтернативы, использовать декларативный подход с SqlDataSource. В идеале наше приложение должно содержать многоуровневую архитектуру, которую можно вызвать программным способом из класса кода программной части страницы или декларативно с помощью элемента управления ObjectDataSource.
Так как в этой серии учебников основное внимание уделяется проверке подлинности на основе форм, авторизации, учетным записям пользователей и ролям, подробного обсуждения этих различных вариантов доступа к данным и причин, почему многоуровневая архитектура предпочтительнее, чем выполнение инструкций SQL непосредственно со страницы ASP.NET. Я собираюсь перейти к использованию DetailsView и SqlDataSource — самого быстрого и простого варианта, но обсуждаемые понятия, безусловно, можно применить к альтернативным веб-элементам управления и логике доступа к данным. Дополнительные сведения о работе с данными в ASP.NET см. в статье Работа с данными в ASP.NET 2.0 .
Откройте страницу в папке Membership
и добавьте на страницу элемент управления DetailsView, установив для его свойства ID значение UserProfile
и очистив его Width
свойства и Height
.AdditionalUserInfo.aspx
Разверните смарт-тег DetailsView и привяжите его к новому элементу управления источником данных. Откроется мастер настройки DataSource (см. рис. 7). На первом шаге требуется указать тип источника данных. Так как мы собираемся подключиться непосредственно к SecurityTutorials
базе данных, выберите значок База данных, указав в ID
качестве UserProfileDataSource
.
Рис. 7. Добавление нового элемента управления SqlDataSource с именем UserProfileDataSource
(щелкните для просмотра полноразмерного изображения)
На следующем экране появится запрос на использование базы данных. Мы уже определили строка подключения для Web.config
SecurityTutorials
базы данных. Это имя строка подключения — SecurityTutorialsConnectionString
должно быть в раскрывающемся списке. Выберите этот параметр и нажмите кнопку Далее.
Рис. 8. Выбор SecurityTutorialsConnectionString
из списка Drop-Down (щелкните для просмотра полноразмерного изображения)
На следующем экране появится запрос на указание таблицы и столбцов для запроса. Выберите таблицу UserProfiles
из раскрывающегося списка и проверка все столбцы.
Рис. 9. Возврат всех столбцов из UserProfiles
таблицы (щелкните для просмотра полноразмерного изображения)
Текущий запрос на рис. 9 возвращает все записи в UserProfiles
, но нас интересует только запись вошедшего в систему пользователя. Чтобы добавить WHERE
предложение, нажмите кнопку WHERE
, чтобы открыть диалоговое окно Добавление WHERE
предложения (см. рис. 10). Здесь можно выбрать столбец для фильтрации, оператор и источник параметра фильтра. Выберите UserId
в качестве столбца и "=" в качестве оператора.
К сожалению, нет встроенного источника параметров для возврата значения вошедшего в систему пользователя UserId
. Нам потребуется захватить это значение программным способом. Поэтому задайте для раскрывающегося списка Источник значение Нет, нажмите кнопку Добавить, чтобы добавить параметр, а затем нажмите кнопку ОК.
Рис. 10. Добавление параметра фильтра в UserId
столбец (щелкните для просмотра полноразмерного изображения)
После нажатия кнопки ОК вы вернеться на экран, показанный на рис. 9. Однако на этот раз SQL-запрос в нижней части экрана должен содержать WHERE
предложение . Нажмите кнопку Далее, чтобы перейти к экрану "Тестовый запрос". Здесь можно выполнить запрос и просмотреть результаты. Чтобы завершить работу мастера, нажмите кнопку Готово.
После завершения работы мастера настройки источника данных Visual Studio создает элемент управления SqlDataSource на основе параметров, указанных в мастере. Кроме того, он вручную добавляет BoundFields в DetailsView для каждого столбца, возвращаемого sqlDataSource SelectCommand
. Нет необходимости отображать UserId
поле в DetailsView, так как пользователю не нужно знать это значение. Это поле можно удалить непосредственно из декларативной разметки элемента управления DetailsView или щелкнув ссылку "Изменить поля" в смарт-теге.
На этом этапе декларативная разметка страницы должна выглядеть примерно так:
<asp:DetailsView ID="UserProfile" runat="server"
AutoGenerateRows="False" DataKeyNames="UserId"
DataSourceID="UserProfileDataSource">
<Fields>
<asp:BoundField DataField="HomeTown" HeaderText="HomeTown"
SortExpression="HomeTown" />
<asp:BoundField DataField="HomepageUrl" HeaderText="HomepageUrl"
SortExpression="HomepageUrl" />
<asp:BoundField DataField="Signature" HeaderText="Signature"
SortExpression="Signature" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="UserProfileDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:SecurityTutorialsConnectionString %>"
SelectCommand="SELECT [UserId], [HomeTown], [HomepageUrl], [Signature] FROM
[UserProfiles] WHERE ([UserId] = @UserId)">
<SelectParameters>
<asp:Parameter Name="UserId" Type="Object" />
</SelectParameters>
</asp:SqlDataSource>
Перед выбором данных необходимо программно задать параметр элемента управления UserId
SqlDataSource для текущего вошедшего пользователя UserId
. Это можно сделать, создав обработчик событий для события SqlDataSource Selecting
и добавив в него следующий код:
Protected Sub UserProfileDataSource_Selecting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceSelectingEventArgs) Handles UserProfileDataSource.Selecting
' Get a reference to the currently logged on user
Dim currentUser As MembershipUser = Membership.GetUser()
' Determine the currently logged on user's UserId value
Dim currentUserId As Guid = CType(currentUser.ProviderUserKey, Guid)
' Assign the currently logged on user's UserId to the @UserId parameter
e.Command.Parameters("@UserId").Value = currentUserId
End Sub
Приведенный выше код начинается с получения ссылки на текущего пользователя, выполнившего вход, путем вызова Membership
метода класса GetUser
. MembershipUser
Возвращает объект , свойство которого ProviderUserKey
содержит UserId
объект . Затем UserId
значение присваивается параметру SqlDataSource @UserId
.
Примечание
Метод Membership.GetUser()
возвращает сведения о вошедшего в систему пользователя. Если анонимный пользователь посещает страницу, он возвращает значение Nothing
. В таком случае при попытке считывания свойства это приведет к NullReferenceException
ошибке в следующей строке ProviderUserKey
кода. Конечно, нам не нужно беспокоиться о Membership.GetUser()
возврате nothing на AdditionalUserInfo.aspx
странице, так как мы настроили авторизацию ПО URL-адреса в предыдущем руководстве, чтобы только прошедшие проверку подлинности пользователи могли получить доступ к ASP.NET ресурсам в этой папке. Если вам нужно получить доступ к сведениям о вошедшего в систему пользователя на странице, на которой разрешен анонимный доступ, убедитесь, что проверка, что MembershipUser
объект, возвращенный методом GetUser()
, не является Nothing, прежде чем ссылаться на его свойства.
Если вы перейдете на страницу AdditionalUserInfo.aspx
через браузер, вы увидите пустую страницу, так как мы еще не добавили строки в таблицу UserProfiles
. На шаге 6 мы рассмотрим, как настроить элемент управления CreateUserWizard для автоматического добавления новой строки в таблицу UserProfiles
при создании новой учетной записи пользователя. Однако пока нам потребуется вручную создать запись в таблице.
Перейдите к Обозреватель базы данных в Visual Studio и разверните папку Таблицы. Щелкните таблицу правой aspnet_Users
кнопкой мыши и выберите команду "Показать данные таблицы", чтобы просмотреть записи в таблице. Сделайте то же самое для UserProfiles
таблицы. На рисунке 11 показаны эти результаты при вертикальном расположении плитки. В моей базе данных в настоящее aspnet_Users
время есть записи для Брюса, Фреда и Тито, но нет записей в UserProfiles
таблице.
Рис. 11. Содержимое aspnet_Users
таблиц и UserProfiles
отображается (щелкните для просмотра полноразмерного изображения)
Добавьте новую запись в таблицу UserProfiles
, вручную введя значения для HomeTown
полей , HomepageUrl
и Signature
. Самый простой способ получить допустимое UserId
значение в новой UserProfiles
записи — выбрать UserId
поле из определенной учетной записи пользователя в aspnet_Users
таблице и скопировать и вставить его в UserId
поле в UserProfiles
. На рисунке 12 показана UserProfiles
таблица после добавления новой записи для Брюса.
Рис. 12. Запись была добавлена UserProfiles
в для Брюса (щелкните, чтобы просмотреть полноразмерное изображение)
Вернитесь в AdditionalUserInfo.aspx page
, вошедший в систему под учетной записью Брюса. Как показано на рисунке 13, отображаются параметры Брюса.
Рис. 13. Для текущего посещающего пользователя отображаются его параметры (щелкните для просмотра полноразмерного изображения)
Примечание
Добавьте записи в таблицу UserProfiles
для каждого пользователя членства вручную. На шаге 6 мы рассмотрим, как настроить элемент управления CreateUserWizard для автоматического добавления новой строки в UserProfiles
таблицу при создании новой учетной записи пользователя.
Шаг 3. Разрешение пользователю изменять свой родной город, домашнюю страницу и подпись
На этом этапе вошедший в систему пользователь может просматривать свой родной город, домашнюю страницу и параметры подписи, но пока не может изменить их. Давайте обновим элемент управления DetailsView, чтобы данные можно было редактировать.
Первое, что нам нужно сделать, — это добавить UpdateCommand
для SqlDataSource, указав выполняемую инструкцию UPDATE
и соответствующие параметры. Выберите SqlDataSource и в окно свойств щелкните многоточие рядом со свойством UpdateQuery, чтобы открыть диалоговое окно Команда и параметр Редактор. Введите в текстовое поле следующую UPDATE
инструкцию:
UPDATE UserProfiles SET
HomeTown = @HomeTown,
HomepageUrl = @HomepageUrl,
Signature = @Signature
WHERE UserId = @UserId
Затем нажмите кнопку "Обновить параметры", которая создаст параметр в коллекции элемента управления UpdateParameters
SqlDataSource для каждого из параметров в инструкции UPDATE
. Оставьте источник для всех параметров равным Нет и нажмите кнопку ОК, чтобы завершить диалоговое окно.
Рис. 14. Укажите sqlDataSource UpdateCommand
и UpdateParameters
(щелкните для просмотра полноразмерного изображения)
Из-за добавлений, внесенных в элемент управления SqlDataSource, элемент управления DetailsView теперь может поддерживать редактирование. В смарт-теге DetailsView проверка флажок "Включить редактирование". При этом commandField добавляется в коллекцию элемента управления Fields
со свойством ShowEditButton
True. При этом отрисовывается кнопка Изменить, когда DetailsView отображается в режиме только для чтения, и кнопки Обновить и Отмена при отображении в режиме редактирования. Вместо того, чтобы пользователь нажимал кнопку Изменить, мы можем настроить отрисовку DetailsView в состоянии "всегда редактируемый", задав для свойства элемента управления DefaultMode
DetailsView значение Edit
.
После этих изменений декларативная разметка элемента управления DetailsView должна выглядеть примерно так:
<asp:DetailsView ID="UserProfile" runat="server"
AutoGenerateRows="False" DataKeyNames="UserId"
DataSourceID="UserProfileDataSource" DefaultMode="Edit">
<Fields>
<asp:BoundField DataField="HomeTown" HeaderText="HomeTown"
SortExpression="HomeTown" />
<asp:BoundField DataField="HomepageUrl" HeaderText="HomepageUrl"
SortExpression="HomepageUrl" />
<asp:BoundField DataField="Signature" HeaderText="Signature"
SortExpression="Signature" />
<asp:CommandField ShowEditButton="True" />
</Fields>
</asp:DetailsView>
Обратите внимание на добавление CommandField и DefaultMode
свойства .
Протестируйте эту страницу в браузере. При посещении с пользователем, у которого есть соответствующая запись в UserProfiles
, параметры пользователя отображаются в редактируемом интерфейсе.
Рис. 15. DetailsView отрисовывает редактируемый интерфейс (щелкните, чтобы просмотреть полноразмерное изображение)
Попробуйте изменить значения и нажать кнопку Обновить. Похоже, ничего не происходит. Существует обратная связь, и значения сохраняются в базе данных, но нет визуальной обратной связи о том, что сохранение произошло.
Чтобы устранить эту проблему, вернитесь в Visual Studio и добавьте элемент управления Метка над DetailsView. Задайте для свойства ID
значение SettingsUpdatedMessage
, для свойства Text
— значение "Ваши параметры были обновлены", а для свойств Visible
и EnableViewState
— значение False
.
<asp:Label ID="SettingsUpdatedMessage" runat="server"
Text="Your settings have been updated."
EnableViewState="false"
Visible="false">
</asp:Label>
Метка должна отображаться SettingsUpdatedMessage
при каждом обновлении DetailsView. Для этого создайте обработчик событий для события DetailsView ItemUpdated
и добавьте следующий код:
Protected Sub UserProfile_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Handles UserProfile.ItemUpdated
SettingsUpdatedMessage.Visible = True
End Sub
Вернитесь на страницу AdditionalUserInfo.aspx
через браузер и обновите данные. На этот раз отображается полезное сообщение о состоянии.
Рис. 16. При обновлении параметров отображается короткое сообщение (щелкните для просмотра полноразмерного изображения)
Примечание
Интерфейс редактирования элемента управления DetailsView оставляет желать лучшего. В нем используются текстовые поля стандартного размера, но поле Подпись, вероятно, должно быть многострочное текстовое поле. Следует использовать RegularExpressionValidator, чтобы URL-адрес домашней страницы, если он был введен, начинался с "http://" или "https://". Кроме того, так как свойство элемента управления DetailsView имеет DefaultMode
значение Edit
, кнопка Отмена ничего не делает. Его следует удалить или перенаправить пользователя на другую страницу (например ~/Default.aspx
, ). Я оставляю эти улучшения как упражнение для читателя.
Добавление ссылки на страницуAdditionalUserInfo.aspx
на главной странице
В настоящее время на веб-сайте нет ссылок на страницу AdditionalUserInfo.aspx
. Единственный способ связаться с ним — ввести URL-адрес страницы непосредственно в адресной строке браузера. Давайте добавим ссылку на эту страницу на Site.master
странице master.
Напомним, что страница master содержит веб-элемент управления LoginView в contentPlaceHolderLoginContent
, который отображает различные разметки для прошедших проверку подлинности и анонимных посетителей. Обновите элемент управления LoggedInTemplate
LoginView, чтобы включить ссылку на страницу AdditionalUserInfo.aspx
. После внесения этих изменений декларативная разметка элемента управления LoginView должна выглядеть примерно так:
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
Welcome back,
<asp:LoginName ID="LoginName1" runat="server" />.
<br />
<asp:HyperLink ID="lnkUpdateSettings" runat="server"
NavigateUrl="~/Membership/AdditionalUserInfo.aspx">
Update Your Settings</asp:HyperLink>
</LoggedInTemplate>
<AnonymousTemplate>
Hello, stranger.
</AnonymousTemplate>
</asp:LoginView>
Обратите внимание на добавление lnkUpdateSettings
элемента управления HyperLink в LoggedInTemplate
. Используя эту ссылку, пользователи, прошедшие проверку подлинности, могут быстро перейти на страницу, чтобы просмотреть и изменить параметры своего родного города, домашней страницы и подписи.
Шаг 4. Добавление новых комментариев гостевой книги
На Guestbook.aspx
этой странице пользователи, прошедшие проверку подлинности, могут просмотреть гостевую книгу и оставить комментарий. Начнем с создания интерфейса для добавления новых комментариев гостевой книги.
Откройте страницу Guestbook.aspx
в Visual Studio и создайте пользовательский интерфейс, состоящий из двух элементов управления TextBox: один для темы нового комментария, а второй — для текста. Задайте для свойства первого элемента управления TextBox значение , а для его Columns
свойства — значение 40, для второго ID
TextMode
MultiLine
Body
— значение , а Width
для свойств и Rows
— значение "95%" и 8 соответственно.Subject
ID
Чтобы завершить работу с пользовательским интерфейсом, добавьте веб-элемент управления Button с именем PostCommentButton
и задайте для его Text
свойства значение "Опубликовать комментарий".
Так как для каждого комментария гостевой книги требуется тема и текст, добавьте RequiredFieldValidator для каждого элемента TextBoxes. Присвойте свойству ValidationGroup
этих элементов управления значение EnterComment; аналогичным образом задайте PostCommentButton
для свойства элемента управления ValidationGroup
значение EnterComment. Дополнительные сведения об ASP. Элементы управления проверки NET, проверка проверку формы в ASP.NET.
После создания пользовательского интерфейса декларативная разметка страницы должна выглядеть примерно так:
<h3>Leave a Comment</h3>
<p>
<b>Subject:</b>
<asp:RequiredFieldValidator ID="SubjectReqValidator" runat="server"
ErrorMessage="You must provide a value for Subject"
ControlToValidate="Subject" ValidationGroup="EnterComment">
</asp:RequiredFieldValidator><br />
<asp:TextBox ID="Subject" Columns="40" runat="server"></asp:TextBox>
</p>
<p>
<b>Body:</b>
<asp:RequiredFieldValidator ID="BodyReqValidator" runat="server"
ControlToValidate="Body"
ErrorMessage="You must provide a value for Body" ValidationGroup="EnterComment">
</asp:RequiredFieldValidator><br />
<asp:TextBox ID="Body" TextMode="MultiLine" Width="95%"
Rows="8" runat="server"></asp:TextBox>
</p>
<p>
<asp:Button ID="PostCommentButton" runat="server"
Text="Post Your Comment"
ValidationGroup="EnterComment" />
</p>
После завершения пользовательского интерфейса наша следующая задача — вставить новую запись в таблицу GuestbookComments
при щелчке PostCommentButton
. Это можно сделать несколькими способами: мы можем написать ADO.NET код в обработчике событий Button Click
; добавить элемент управления SqlDataSource на страницу, настроить его InsertCommand
, а затем вызвать его Insert
метод из Click
обработчика событий; или создать средний уровень, отвечающий за вставку новых комментариев гостевой книги, и вызвать эту функцию из Click
обработчика событий. Так как мы рассмотрели использование SqlDataSource на шаге 3, давайте используем ADO.NET код здесь.
Примечание
Классы ADO.NET, используемые для программного доступа к данным из базы данных Microsoft SQL Server, находятся в System.Data.SqlClient
пространстве имен . Может потребоваться импортировать это пространство имен в класс кода программной части страницы (т. е. Imports System.Data.SqlClient
).
Создайте обработчик событий для PostCommentButton
Click
события и добавьте следующий код:
Protected Sub PostCommentButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles PostCommentButton.Click
If Not Page.IsValid Then Exit Sub
' Determine the currently logged on user's UserId
Dim currentUser As MembershipUser = Membership.GetUser()
Dim currentUserId As Guid = CType(currentUser.ProviderUserKey, Guid)
' Insert a new record into GuestbookComments
Dim connectionString As String =
ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString
Dim insertSql As String = "INSERT INTO GuestbookComments(Subject, Body, UserId)
VALUES(@Subject, @Body, @UserId)"
Using myConnection As New SqlConnection(connectionString)
myConnection.Open()
Dim myCommand As New SqlCommand(insertSql, myConnection)
myCommand.Parameters.AddWithValue("@Subject", Subject.Text.Trim())
myCommand.Parameters.AddWithValue("@Body", Body.Text.Trim())
myCommand.Parameters.AddWithValue("@UserId", currentUserId)
myCommand.ExecuteNonQuery()
myConnection.Close()
End Using
' "Reset" the Subject and Body TextBoxes
Subject.Text = String.Empty
Body.Text = String.Empty
End Sub
Обработчик Click
событий начинается с проверки допустимости предоставленных пользователем данных. Если это не так, обработчик событий завершает работу перед вставкой записи. При условии, что предоставленные данные являются допустимыми, текущее значение пользователя UserId
, вошедшего в систему, извлекается и сохраняется в локальной переменной currentUserId
. Это значение необходимо, так как необходимо указать UserId
значение при вставке записи в GuestbookComments
.
После этого из базы данных извлекается Web.config
строка подключения SecurityTutorials
и INSERT
указывается инструкция SQL. SqlConnection
Затем создается и открывается объект . SqlCommand
Затем создается объект и назначаются значения для параметров, используемых в запросеINSERT
. Затем INSERT
выполняется инструкция и соединение закрывается. В конце обработчика событий свойства и Body
TextBoxes Text
очищаются, Subject
чтобы значения пользователя не сохранялись во время обратной передачи.
Протестируйте эту страницу в браузере. Так как эта страница находится в папке Membership
, она недоступна анонимным посетителям. Поэтому необходимо сначала войти в систему (если это еще не сделано). Введите значение в Subject
и Body
TextBoxes и нажмите кнопку PostCommentButton
. Это приведет к добавлению новой записи в GuestbookComments
. При обратной отправке указанные тема и текст удаляются из textBoxes.
После нажатия кнопки PostCommentButton
визуальный отзыв о добавлении комментария в гостевую книгу отсутствует. Нам по-прежнему нужно обновить эту страницу для отображения существующих комментариев гостевой книги, что мы сделаем на шаге 5. После этого только что добавленный комментарий появится в списке комментариев, обеспечивая адекватную визуальную обратную связь. На данный момент убедитесь, что комментарий гостевой книги сохранен, изучив содержимое GuestbookComments
таблицы.
На рисунке 17 показано содержимое GuestbookComments
таблицы после того, как остались два комментария.
Рис. 17. Вы можете просмотреть примечания гостевой книги GuestbookComments
в таблице (щелкните, чтобы просмотреть полноразмерное изображение)
Примечание
Если пользователь пытается вставить комментарий гостевой книги, содержащий потенциально опасную разметку, например HTML, ASP.NET вызовет HttpRequestValidationException
исключение . Дополнительные сведения об этом исключении, причинах его возникновения и о том, как разрешить пользователям отправлять потенциально опасные значения, см. в технической документации по проверке запросов.
Шаг 5. Перечисление существующих комментариев гостевой книги
Помимо примечаний, пользователь, посещающий страницу Guestbook.aspx
, также должен иметь возможность просматривать существующие комментарии гостевой книги. Для этого добавьте элемент управления ListView с именем CommentList
в нижнюю часть страницы.
Примечание
Элемент управления ListView является новым для ASP.NET версии 3.5. Он предназначен для отображения списка элементов в очень настраиваемом и гибком макете, но по-прежнему предлагает встроенные функции редактирования, вставки, удаления, разбиения по страницам и сортировки, такие как GridView. Если вы используете ASP.NET 2.0, вам потребуется использовать элемент управления DataList или Repeater. Дополнительные сведения об использовании ListView см. в записи блога Скотта Гатри, Элемент управления asp:ListView и в моей статье Отображение данных с помощью элемента управления ListView.
Откройте смарт-тег ListView и в раскрывающемся списке Выбор источника данных привяжите элемент управления к новому источнику данных. Как мы видели на шаге 2, запустится мастер настройки источника данных. Щелкните значок База данных, назовите результирующий SqlDataSource CommentsDataSource
и нажмите кнопку ОК. Затем выберите SecurityTutorialsConnectionString
строка подключения из раскрывающегося списка и нажмите кнопку Далее.
На этом этапе на шаге 2 мы указали данные для запроса, выбрав таблицу UserProfiles
из раскрывающегося списка и выбрав возвращаемые столбцы (см. рис. 9). Однако на этот раз мы хотим создать инструкцию SQL, которая извлекает не только записи из GuestbookComments
, но и родной город, домашнюю страницу, подпись и имя пользователя комментатора. Поэтому установите переключатель "Указать настраиваемую инструкцию SQL или хранимую процедуру" и нажмите кнопку Далее.
Откроется экран "Определение пользовательских инструкций или хранимых процедур". Нажмите кнопку Построитель запросов, чтобы выполнить графическую сборку запроса. Построитель запросов начинается с запроса на указание таблиц, из которого требуется выполнить запрос. GuestbookComments
Выберите таблицы , UserProfiles
и aspnet_Users
и нажмите кнопку ОК. При этом все три таблицы будут добавлены в область конструктора. Так как в GuestbookComments
таблицах , UserProfiles
и aspnet_Users
существуют ограничения внешнего ключа, построитель запросов автоматически создает JOIN
эти таблицы.
Остается только указать возвращаемые столбцы. GuestbookComments
В таблице выберите Subject
столбцы , Body
и CommentDate
; возвращать HomeTown
столбцы , HomepageUrl
и Signature
из UserProfiles
таблицы; возвращать UserName
из aspnet_Users
. Кроме того, добавьте "ORDER BY CommentDate DESC
" в конец SELECT
запроса, чтобы сначала возвращались самые последние записи. После выбора этих элементов интерфейс построителя запросов должен выглядеть примерно так, как на снимке экрана на рисунке 18.
Рис. 18. Созданный запрос JOIN
GuestbookComments
с таблицами , UserProfiles
и aspnet_Users
(щелкните для просмотра полноразмерного изображения)
Нажмите кнопку ОК, чтобы закрыть окно построителя запросов и вернуться на экран "Определение пользовательских инструкций или хранимых процедур". Нажмите кнопку Далее, чтобы перейти на экран "Тестовый запрос", где можно просмотреть результаты запроса, нажав кнопку Тестовый запрос. Когда все будет готово, нажмите кнопку Готово, чтобы завершить работу мастера настройки источника данных.
После завершения работы мастера настройки источника данных на шаге 2 коллекция связанного элемента управления DetailsView была обновлена Fields
для включения BoundField для каждого столбца, возвращаемого SelectCommand
объектом . ListView, однако, остается без изменений; Нам по-прежнему нужно определить его макет. Макет ListView можно создать вручную с помощью декларативной разметки или с помощью параметра "Настроить ListView" в смарт-теге. Я обычно предпочитаю определять разметку вручную, но использовать любой метод является наиболее естественным для вас.
В итоге я использовал следующие LayoutTemplate
, ItemTemplate
и ItemSeparatorTemplate
для элемента управления ListView:
<asp:ListView ID="CommentList" runat="server" DataSourceID="CommentsDataSource">
<LayoutTemplate>
<span ID="itemPlaceholder" runat="server" />
<p>
<asp:DataPager ID="DataPager1" runat="server">
<Fields>
<asp:NextPreviousPagerField ButtonType="Button"
ShowFirstPageButton="True"
ShowLastPageButton="True" />
</Fields>
</asp:DataPager>
</p>
</LayoutTemplate>
<ItemTemplate>
<h4>
<asp:Label ID="SubjectLabel" runat="server"
Text='<%# Eval("Subject") %>' />
</h4>
<asp:Label ID="BodyLabel" runat="server"
Text='<%# Eval("Body").ToString().Replace(Environment.NewLine, "<br />") %>' />
<p>
---<br />
<asp:Label ID="SignatureLabel" Font-Italic="true" runat="server"
Text='<%# Eval("Signature") %>' />
<br />
<br />
My Home Town:
<asp:Label ID="HomeTownLabel" runat="server"
Text='<%# Eval("HomeTown") %>' />
<br />
My Homepage:
<asp:HyperLink ID="HomepageUrlLink" runat="server"
NavigateUrl='<%# Eval("HomepageUrl") %>'
Text='<%# Eval("HomepageUrl") %>' />
</p>
<p align="center">
Posted by
<asp:Label ID="UserNameLabel" runat="server"
Text='<%# Eval("UserName") %>' />
on
<asp:Label ID="CommentDateLabel" runat="server"
Text='<%# Eval("CommentDate") %>' />
</p>
</ItemTemplate>
<ItemSeparatorTemplate>
<hr />
</ItemSeparatorTemplate>
</asp:ListView>
определяет LayoutTemplate
разметку, выдаваемую элементом управления , в то время как ItemTemplate
отрисовывает каждый элемент, возвращаемый SqlDataSource. Результирующая ItemTemplate
разметка помещается в LayoutTemplate
элемент управления itemPlaceholder
. Помимо itemPlaceholder
, LayoutTemplate
включает элемент управления DataPager, который ограничивает ListView отображением всего 10 комментариев гостевой книги на странице (по умолчанию) и отображает интерфейс подкачки.
My ItemTemplate
отображает тему каждого комментария гостевой книги в <h4>
элементе с текстом, расположенным под темой. Обратите внимание, что синтаксис, используемый для отображения текста, принимает данные, возвращаемые оператором Eval("Body")
привязки данных, преобразует их в строку и заменяет разрывы строк элементом <br />
. Это преобразование необходимо для отображения разрывов строк, введенных при отправке комментария, так как пробел игнорируется HTML. Подпись пользователя отображается под текстом курсивом, за которым следует родной город пользователя, ссылка на его домашнюю страницу, дата и время создания комментария, а также имя пользователя, который оставил комментарий.
Просмотрите страницу в браузере. Здесь должны отобразиться комментарии, добавленные в гостевую книгу на шаге 5.
Рис. 19. Guestbook.aspx
Теперь отображаются примечания гостевой книги (щелкните для просмотра полноразмерного изображения)
Попробуйте добавить новый комментарий в гостевую книгу. После нажатия кнопки PostCommentButton
страница выполняет обратную запись, и комментарий добавляется в базу данных, но элемент управления ListView не обновляется для отображения нового комментария. Это можно исправить с помощью следующих способов:
PostCommentButton
Обновление обработчикаClick
событий кнопки таким образом, чтобы он вызвал метод элемента управленияDataBind()
ListView после вставки нового комментария в базу данных;- Присвойите свойству элемента управления
EnableViewState
ListView значениеFalse
. Этот подход работает, потому что, отключив состояние представления элемента управления, он должен повторно привязывать к базовым данным при каждой обратной отправке.
На веб-сайте учебника, который можно скачать из этого руководства, показаны оба метода. Свойство элемента управления EnableViewState
ListView и False
код, необходимый для программной повторной привязки данных к ListView, присутствует в обработчике Click
событий, но закомментирован.
Примечание
В настоящее AdditionalUserInfo.aspx
время страница позволяет пользователю просматривать и изменять параметры своего родного города, домашней страницы и подписи. Было бы неплохо обновить AdditionalUserInfo.aspx
, чтобы отобразить комментарии гостевой книги пользователя, выполнившего вход. То есть, помимо изучения и изменения информации, пользователь может посетить страницу AdditionalUserInfo.aspx
, чтобы увидеть, какие комментарии гостевой книги он сделал в прошлом. Я оставляю это как упражнение для заинтересованного читателя.
Шаг 6. Настройка элемента управления CreateUserWizard для включения интерфейса для домашнего города, домашней страницы и подписи
Запрос SELECT
, используемый страницей Guestbook.aspx
INNER JOIN
, использует для объединения связанных записей между GuestbookComments
таблицами , UserProfiles
и aspnet_Users
. Если пользователь, у которого нет записи в UserProfiles
, делает комментарий гостевой книги, комментарий не будет отображаться в ListView, так как INNER JOIN
возвращает GuestbookComments
записи только при наличии совпадающих записей в UserProfiles
и aspnet_Users
. И, как мы видели на шаге 3, если у пользователя нет записи, UserProfiles
он не может просматривать или изменять свои параметры на AdditionalUserInfo.aspx
странице.
Нет необходимости говорить, что из-за наших решений по проектированию важно, чтобы каждая учетная запись пользователя в системе членства была соответствующая запись в UserProfiles
таблице. Нам нужно, чтобы соответствующая запись добавлялась UserProfiles
в каждый раз, когда создается новая учетная запись пользователя членства с помощью CreateUserWizard.
Как описано в руководстве По созданию учетных записей пользователей, после создания новой учетной записи участника элемент управления CreateUserWizard вызывает событиеCreatedUser
. Мы можем создать обработчик событий для этого события, получить Идентификатор пользователя для только что созданного пользователя, а затем вставить запись в таблицу UserProfiles
со значениями по умолчанию для HomeTown
столбцов , HomepageUrl
и Signature
. Более того, можно заставить у пользователя эти значения, настроив интерфейс элемента управления CreateUserWizard, чтобы включить дополнительные элементы TextBoxes.
Сначала рассмотрим, как добавить новую строку в таблицу UserProfiles
в обработчике CreatedUser
событий со значениями по умолчанию. После этого мы посмотрим, как настроить пользовательский интерфейс элемента управления CreateUserWizard, чтобы включить дополнительные поля формы для сбора домашней страницы, домашней страницы и подписи нового пользователя.
Добавление строки по умолчанию вUserProfiles
В учебнике Создание учетных записей пользователей мы добавили элемент управления CreateUserWizard на страницу CreatingUserAccounts.aspx
в папке Membership
. Чтобы элемент управления CreateUserWizard добавлял запись в таблицу UserProfiles
при создании учетной записи пользователя, необходимо обновить функциональные возможности элемента управления CreateUserWizard. Вместо того, чтобы вносить эти изменения на страницу CreatingUserAccounts.aspx
, давайте добавим новый элемент управления CreateUserWizard на страницу EnhancedCreateUserWizard.aspx
и внесите изменения для этого руководства.
Откройте страницу EnhancedCreateUserWizard.aspx
в Visual Studio и перетащите элемент управления CreateUserWizard из панели элементов на страницу. Задайте для свойства элемента управления ID
CreateUserWizard значение NewUserWizard
. Как мы говорили в руководстве по созданию учетных записей пользователей , пользовательский интерфейс CreateUserWizard по умолчанию запрашивает у посетителя необходимые сведения. После того как эта информация будет предоставлена, элемент управления внутренне создает новую учетную запись пользователя на платформе членства, при этом нам не нужно писать ни одной строки кода.
Элемент управления CreateUserWizard вызывает ряд событий во время рабочего процесса. После того как посетитель предоставляет сведения о запросе и отправляет форму, элемент управления CreateUserWizard сначала запускает своеCreatingUser
событие. Если во время создания возникла проблема, CreateUserError
событие запускается; однако, если пользователь успешно создан, CreatedUser
возникает событие . В руководстве по созданию учетных записей пользователей мы создали обработчик событий для CreatingUser
события, чтобы убедиться, что указанное имя пользователя не содержит начальных или конечных пробелов и что имя пользователя не отображается в пароле.
Чтобы добавить строку в таблицу UserProfiles
для только что созданного пользователя, необходимо создать обработчик CreatedUser
события. К моменту CreatedUser
запуска события учетная запись пользователя уже была создана на платформе членства, что позволяет нам получить значение UserId учетной записи.
Создайте обработчик событий для NewUserWizard
CreatedUser
события и добавьте следующий код:
Protected Sub NewUserWizard_CreatedUser(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewUserWizard.CreatedUser
' Get the UserId of the just-added user
Dim newUser As MembershipUser = Membership.GetUser(NewUserWizard.UserName)
Dim newUserId As Guid = CType(newUser.ProviderUserKey, Guid)
' Insert a new record into UserProfiles
Dim connectionString As String =
ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString
Dim insertSql As String = "INSERT INTO UserProfiles(UserId, HomeTown, HomepageUrl,
Signature) VALUES(@UserId, @HomeTown, @HomepageUrl, @Signature)"
Using myConnection As New SqlConnection(connectionString)
myConnection.Open()
Dim myCommand As New SqlCommand(insertSql, myConnection)
myCommand.Parameters.AddWithValue("@UserId", newUserId)
myCommand.Parameters.AddWithValue("@HomeTown", DBNull.Value)
myCommand.Parameters.AddWithValue("@HomepageUrl", DBNull.Value)
myCommand.Parameters.AddWithValue("@Signature", DBNull.Value)
myCommand.ExecuteNonQuery()
myConnection.Close()
End Using
End Sub
Приведенный выше код используется путем получения Идентификатора пользователя только что добавленной учетной записи пользователя. Это достигается с помощью Membership.GetUser(username)
метода для возврата сведений о конкретном пользователе, а затем с помощью ProviderUserKey
свойства для получения идентификатора пользователя. Имя пользователя, введенное пользователем в элементе управления CreateUserWizard, доступно через его UserName
свойство .
Затем извлекается строка подключения и Web.config
INSERT
указывается оператор . Создаются необходимые объекты ADO.NET и выполняется команда . Код назначает DBNull
экземпляр параметрам , @HomepageUrl
и @Signature
, что приводит к @HomeTown
вставке значений HomeTown
базы данных NULL
для полей , HomepageUrl
и Signature
.
Перейдите на страницу EnhancedCreateUserWizard.aspx
в браузере и создайте учетную запись пользователя. После этого вернитесь в Visual Studio и изучите содержимое aspnet_Users
таблиц и UserProfiles
(как это было на рисунке 12). Вы увидите новую учетную запись пользователя в aspnet_Users
и соответствующую UserProfiles
строку (со значениями NULL
HomeTown
, HomepageUrl
и Signature
).
Рис. 20. Добавлена новая учетная запись пользователя и UserProfiles
запись (щелкните для просмотра полноразмерного изображения)
После того как посетитель предоставил сведения о своей новой учетной записи и нажал кнопку "Создать пользователя", учетная запись пользователя будет создана, а в таблицу UserProfiles
добавляется строка. Затем элемент CreateUserWizard отображает его CompleteWizardStep
, который отображает сообщение об успешном выполнении и кнопку Продолжить. Нажатие кнопки Продолжить приводит к обратной отправке, но никаких действий не выполняется, в результате чего пользователь зависает на EnhancedCreateUserWizard.aspx
странице.
Можно указать URL-адрес для отправки пользователю при нажатии кнопки Продолжить с помощью свойства элемента управления ContinueDestinationPageUrl
CreateUserWizard. ContinueDestinationPageUrl
Задайте для свойства значение "~/Membership/AdditionalUserInfo.aspx". При этом новый пользователь перейдет в AdditionalUserInfo.aspx
, где он может просматривать и обновлять свои параметры.
Настройка интерфейса CreateUserWizard для запроса домашнего города, домашней страницы и подписи нового пользователя
Интерфейса по умолчанию элемента управления CreateUserWizard достаточно для простых сценариев создания учетных записей, в которых необходимо собирать только основные сведения об учетной записи пользователя, такие как имя пользователя, пароль и электронная почта. Но что делать, если мы хотим предложить посетителю войти в ее родной город, домашнюю страницу, и подпись при создании ее учетной записи? Интерфейс элемента управления CreateUserWizard можно настроить для сбора дополнительных сведений при регистрации. Эти сведения можно использовать в CreatedUser
обработчике событий для вставки дополнительных записей в базовую базу данных.
Элемент управления CreateUserWizard расширяет элемент управления мастер ASP.NET, который является элементом управления, который позволяет разработчику страниц определить ряд упорядоченных WizardSteps
. Элемент управления "Мастер" отображает активный шаг и предоставляет интерфейс навигации, позволяющий посетителю пройти эти шаги. Элемент управления "Мастер" идеально подходит для разбиения длинной задачи на несколько коротких шагов. Дополнительные сведения об элементе управления "Мастер" см. в разделе Создание пошагового пользовательского интерфейса с помощью элемента управления мастера ASP.NET 2.0.
Разметка элемента управления CreateUserWizard по умолчанию определяет два WizardSteps
: CreateUserWizardStep
и CompleteWizardStep
.
<asp:CreateUserWizard ID="NewUserWizard" runat="server"
ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
<WizardSteps>
<asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
</asp:CreateUserWizardStep>
<asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
</asp:CompleteWizardStep>
</WizardSteps>
</asp:CreateUserWizard>
Первый WizardStep
, CreateUserWizardStep
отображает интерфейс, который запрашивает имя пользователя, пароль, адрес электронной почты и т. д. Когда посетитель предоставляет эти сведения и нажимает кнопку "Создать пользователя", ей отображается CompleteWizardStep
сообщение об успешном выполнении и кнопка Продолжить.
Чтобы настроить интерфейс элемента управления CreateUserWizard для включения дополнительных полей формы, можно:
Создание одного или нескольких новых
WizardStep
, чтобы содержать дополнительные элементы пользовательского интерфейса. Чтобы добавить новыйWizardStep
объект в CreateUserWizard, щелкните ссылку "Добавить или удалитьWizardStep
" в смарт-теге, чтобы запуститьWizardStep
Редактор коллекции. Оттуда можно добавить, удалить или изменить порядок действий в мастере. Это подход, который мы будем использовать в этом руководстве.CreateUserWizardStep
Преобразованиев редактируемый объектWizardStep
. Это заменяет наCreateUserWizardStep
эквивалентWizardStep
, разметка которого определяет пользовательский интерфейс, соответствующийCreateUserWizardStep
. Преобразовав вCreateUserWizardStep
,WizardStep
можно изменить положение элементов управления или добавить дополнительные элементы пользовательского интерфейса на этом шаге. Чтобы преобразоватьCreateUserWizardStep
илиCompleteWizardStep
в редактируемыйWizardStep
, щелкните ссылку "Настроить шаг создания пользователя" или "Настроить полный шаг" в смарт-теге элемента управления.Используйте некоторое сочетание указанных выше двух вариантов.
Важно помнить, что элемент управления CreateUserWizard выполняет процесс создания учетной записи пользователя при нажатии кнопки "Создать пользователя" в его CreateUserWizardStep
. Не имеет значения, есть ли дополнительные WizardStep
после CreateUserWizardStep
или нет.
При добавлении пользовательского в WizardStep
элемент управления CreateUserWizard для сбора дополнительных пользовательских данных WizardStep
пользователь может быть размещен до или после CreateUserWizardStep
. Если он поставляется до CreateUserWizardStep
, то для обработчика событий доступны дополнительные входные данные, собранные пользователем из пользовательского WizardStep
CreatedUser
объекта . Однако если пользователь WizardStep
возникает после CreateUserWizardStep
, то к тому времени, когда WizardStep
пользователь отображается, новая учетная запись пользователя уже создана и CreatedUser
событие уже сработало.
На рисунке 21 показан рабочий процесс, когда добавленный WizardStep
предшествует CreateUserWizardStep
. Так как к моменту CreatedUser
возникновения события были собраны дополнительные сведения о пользователе, достаточно обновить CreatedUser
обработчик событий, чтобы получить эти входные данные и использовать их для INSERT
значений параметров инструкции (а не DBNull.Value
).
Рис. 21. Рабочий процесс CreateUserWizard, когда перед элементом Additional WizardStep
предшествует CreateUserWizardStep
(щелкните для просмотра полноразмерного изображения)
Если пользователь WizardStep
размещается послеCreateUserWizardStep
, процесс создания учетной записи пользователя происходит до того, как пользователь может войти в свой родной город, домашнюю страницу или подпись. В этом случае эти дополнительные сведения необходимо вставить в базу данных после создания учетной записи пользователя, как показано на рисунке 22.
Рис. 22. Рабочий процесс CreateUserWizard При дополнительном WizardStep
наступает после CreateUserWizardStep
(щелкните для просмотра полноразмерного изображения)
Рабочий процесс, показанный на рис. 22, ожидает вставки записи в таблицу UserProfiles
до завершения шага 2. Однако если посетитель закроет браузер после шага 1, мы достигли состояния, в котором была создана учетная запись пользователя, но запись не была добавлена в UserProfiles
. Одним из обходных решений является вставка UserProfiles
записи со значениями NULL
или по умолчанию в CreatedUser
обработчик событий (которая возникает после шага 1), а затем обновление этой записи после завершения шага 2. Это гарантирует, что UserProfiles
запись будет добавлена для учетной записи пользователя, даже если пользователь завершит процесс регистрации в середине.
В этом руководстве давайте создадим новый WizardStep
объект, который возникает после , CreateUserWizardStep
но перед CompleteWizardStep
. Давайте сначала настроим МастерШаг, а затем рассмотрим код.
В смарт-теге элемента управления CreateUserWizard выберите "Добавить/удалитьWizardStep
", в котором откроется диалоговое WizardStep
окно Редактор коллекция. Добавьте новый WizardStep
объект , задав для нее ID
значение UserSettings
, а для Title
параметра — значение "Ваши параметры" и значение StepType
Step
. Затем разместите его так, чтобы он располагал после CreateUserWizardStep
("Регистрация для новой учетной записи") и перед CompleteWizardStep
("Завершить"), как показано на рис. 23.
Рис. 23. Добавление нового WizardStep
элемента управления CreateUserWizard (щелкните для просмотра полноразмерного изображения)
Нажмите кнопку ОК, чтобы закрыть диалоговое WizardStep
окно Редактор коллекции. О новом WizardStep
свидетельствует обновленная декларативная разметка элемента управления CreateUserWizard:
<asp:CreateUserWizard ID="NewUserWizard" runat="server"
ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
<WizardSteps>
<asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
</asp:CreateUserWizardStep>
<asp:WizardStep runat="server" ID="UserSettings" StepType="Step"
Title="Your Settings">
</asp:WizardStep>
<asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
</asp:CompleteWizardStep>
</WizardSteps>
</asp:CreateUserWizard>
Обратите внимание на новый <asp:WizardStep>
элемент . Нам нужно добавить пользовательский интерфейс для сбора родного города, домашней страницы и подписи нового пользователя здесь. Это содержимое можно ввести в декларативном синтаксисе или с помощью Designer. Чтобы использовать Designer, выберите шаг "Параметры" в раскрывающемся списке смарт-тега, чтобы просмотреть этот шаг в Designer.
Примечание
При выборе шага в раскрывающемся списке Смарт-тега обновляется свойство элемента управления ActiveStepIndex
CreateUserWizard, указывающее индекс начального шага. Поэтому если вы используете этот раскрывающийся список для изменения шага "Ваши параметры" в Designer, обязательно установите для него значение "Регистрация для новой учетной записи", чтобы этот шаг отображалось при первом посещении EnhancedCreateUserWizard.aspx
страницы пользователями.
Создайте пользовательский интерфейс на шаге "Параметры", который содержит три элемента управления TextBox с именами HomeTown
, HomepageUrl
и Signature
. После создания этого интерфейса декларативная разметка CreateUserWizard должна выглядеть примерно так:
<asp:CreateUserWizard ID="NewUserWizard" runat="server"
ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
<WizardSteps>
<asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
</asp:CreateUserWizardStep>
<asp:WizardStep runat="server" ID="UserSettings" StepType="Step"
Title="Your Settings">
<p>
<b>Home Town:</b><br />
<asp:TextBox ID="HomeTown" runat="server"></asp:TextBox>
</p>
<p>
<b>Homepage URL:</b><br />
<asp:TextBox ID="HomepageUrl" Columns="40" runat="server"></asp:TextBox>
</p>
<p>
<b>Signature:</b><br />
<asp:TextBox ID="Signature" TextMode="MultiLine" Width="95%"
Rows="5" runat="server"></asp:TextBox>
</p>
</asp:WizardStep>
<asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
</asp:CompleteWizardStep>
</WizardSteps>
</asp:CreateUserWizard>
Перейдите на эту страницу в браузере и создайте учетную запись пользователя, указав значения для родного города, домашней страницы и подписи. После завершения CreateUserWizardStep
действия учетная запись пользователя создается на платформе членства и CreatedUser
запускается обработчик событий, который добавляет новую строку в UserProfiles
, но со значением HomeTown
базы данных NULL
, HomepageUrl
и Signature
. Значения, введенные для родного города, домашней страницы и подписи, никогда не используются. Конечным результатом является новая учетная запись пользователя с записью UserProfiles
, поля которой HomeTown
, HomepageUrl
и Signature
еще не указаны.
Нам нужно выполнить код после шага "Параметры", который принимает значения родного города, honepage и сигнатуры, введенные пользователем, и обновляет соответствующую UserProfiles
запись. Каждый раз, когда пользователь перемещается между шагами в элементе управления "Мастер"ActiveStepChanged
, возникает событие мастера. Мы можем создать обработчик событий для этого события и обновить таблицу UserProfiles
после завершения шага "Параметры".
Добавьте обработчик событий для события CreateUserWizard ActiveStepChanged
и добавьте следующий код:
Protected Sub NewUserWizard_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewUserWizard.ActiveStepChanged
' Have we JUST reached the Complete step?
If NewUserWizard.ActiveStep.Title = "Complete" Then
Dim UserSettings As WizardStep = CType(NewUserWizard.FindControl("UserSettings"),WizardStep)
' Programmatically reference the TextBox controls
Dim HomeTown As TextBox = CType(UserSettings.FindControl("HomeTown"), TextBox)
Dim HomepageUrl As TextBox = CType(UserSettings.FindControl("HomepageUrl"), TextBox)
Dim Signature As TextBox = CType(UserSettings.FindControl("Signature"), TextBox)
' Update the UserProfiles record for this user
' Get the UserId of the just-added user
Dim newUser As MembershipUser = Membership.GetUser(NewUserWizard.UserName)
Dim newUserId As Guid = CType(newUser.ProviderUserKey, Guid)
' Insert a new record into UserProfiles
Dim connectionString As String = ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString
Dim updateSql As String = "UPDATE UserProfiles SET HomeTown = @HomeTown, HomepageUrl
= @HomepageUrl, Signature = @Signature WHERE UserId = @UserId"
Using myConnection As New SqlConnection(connectionString)
myConnection.Open()
Dim myCommand As New SqlCommand(updateSql, myConnection)
myCommand.Parameters.AddWithValue("@HomeTown", HomeTown.Text.Trim())
myCommand.Parameters.AddWithValue("@HomepageUrl", HomepageUrl.Text.Trim())
myCommand.Parameters.AddWithValue("@Signature", Signature.Text.Trim())
myCommand.Parameters.AddWithValue("@UserId", newUserId)
myCommand.ExecuteNonQuery()
myConnection.Close()
End Using
End If
End Sub
Приведенный выше код начинается с определения того, достигли ли мы только что шага "Завершить". Так как шаг "Завершить" происходит сразу после шага "Ваши параметры", то, когда посетитель достигает шага "Завершить", это означает, что он только что завершил шаг "Ваши параметры".
В этом случае необходимо программно ссылаться на элементы управления TextBox в UserSettings WizardStep
. Для этого сначала используется FindControl
метод для программной ссылки на UserSettings WizardStep
, а затем снова для ссылки на TextBoxes из WizardStep
. После того как на TextBoxes будет указана ссылка, мы готовы выполнить инструкцию UPDATE
. Оператор UPDATE
имеет то же количество параметров, что INSERT
и оператор в CreatedUser
обработчике событий, но здесь мы используем значения родной город, домашняя страница и подпись, предоставленные пользователем.
С помощью этого обработчика событий перейдите на страницу EnhancedCreateUserWizard.aspx
в браузере и создайте учетную запись пользователя, указав значения для родного города, домашней страницы и подписи. После создания новой учетной записи вы будете перенаправлены на AdditionalUserInfo.aspx
страницу, где отображаются только что введенные сведения о родном городе, домашней странице и подписи.
Примечание
Сейчас на нашем веб-сайте есть две страницы, на которых посетитель может создать новую учетную запись: CreatingUserAccounts.aspx
и EnhancedCreateUserWizard.aspx
. Карта сайта и страница входа на веб-сайте указывают на CreatingUserAccounts.aspx
страницу, но CreatingUserAccounts.aspx
страница не запрашивает у пользователя сведения о родном городе, домашней странице и подписи и не добавляет соответствующую строку в UserProfiles
. Поэтому либо обновите страницу CreatingUserAccounts.aspx
, чтобы она предлагала эту функцию, либо обновите карту сайта и страницу входа на ссылку EnhancedCreateUserWizard.aspx
вместо CreatingUserAccounts.aspx
. Если вы выбрали последний вариант, обязательно обновите Membership
файл папки Web.config
, чтобы разрешить анонимным пользователям доступ к EnhancedCreateUserWizard.aspx
странице.
Сводка
В этом руководстве мы рассмотрели методы моделирования данных, связанных с учетными записями пользователей на платформе членства. В частности, мы рассмотрели моделирование сущностей, которые совместно используют связь "один ко многим" с учетными записями пользователей, а также данные, которые имеют отношение "один к одному". Кроме того, мы узнали, как эти связанные сведения могут отображаться, вставляться и обновляться, в некоторых примерах используется элемент управления SqlDataSource, а другие — с помощью ADO.NET кода.
В этом руководстве мы завершаем работу с учетными записями пользователей. Начиная со следующего руководства мы рассмотрим роли. В следующих руководствах мы рассмотрим платформу ролей, узнаем, как создавать новые роли, как назначать роли пользователям, как определить, к каким ролям принадлежит пользователь, и как применить авторизацию на основе ролей.
Счастливое программирование!
Дополнительные материалы
Дополнительные сведения по темам, рассматриваемым в этом руководстве, см. в следующих ресурсах:
- Доступ к данным и их обновление в ASP.NET 2.0
- Элемент управления мастера ASP.NET 2.0
- Создание пошагового пользовательского интерфейса с помощью элемента управления мастера ASP.NET 2.0
- Создание пользовательских параметров элемента управления DataSource
- Настройка элемента управления CreateUserWizard
- СведенияПросмотр кратких руководств по элементам управления
- Отображение данных с помощью элемента управления ListView
- Разбор элементов управления проверкой в ASP.NET 2.0
- Изменение вставки и удаления данных
- Проверка формы в ASP.NET
- Сбор пользовательских сведений о регистрации пользователей
- Профили в ASP.NET 2.0
- Элемент управления asp:ListView
- Краткое руководство по профилям пользователей
Об авторе
Скотт Митчелл (Scott Mitchell), автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часа. Скотт можно связаться по адресу mitchell@4guysfromrolla.com или через его блог по адресу http://ScottOnWriting.NET.
Отдельная благодарность...
Эта серия учебников была проверена многими полезными рецензентами. Хотите ознакомиться с моими предстоящими статьями MSDN? Если да, опустите мне строку в mitchell@4GuysFromRolla.com.