Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Пранав Растоги( Pranav Rastogi),Рик Андерсон (Rick Anderson),Роберт Макмюррей (Robert McMurray),Сухас Джоши (Suhas Joshi)
В этом руководстве описаны шаги, необходимые для переноса данных пользователей и ролей, а также данных профилей пользователей, созданных с помощью универсальные поставщики существующего приложения, в модель ASP.NET identity. Упомянутый здесь подход к переносу данных профилей пользователей также можно использовать в приложении с членством в SQL.
С выпуском Visual Studio 2013 команда ASP.NET представила новую систему удостоверений ASP.NET. Дополнительные сведения об этом выпуске см. здесь. В этой статье описано, как перенести веб-приложения из членства SQL в новую систему удостоверений, в этой статье показаны шаги по переносу существующих приложений, которые соответствуют модели поставщиков для управления пользователями и ролями, в новую модель удостоверений. В этом руководстве основное внимание уделяется переносу данных профиля пользователя, чтобы легко подключить их к новой системе. Перенос сведений о пользователях и ролях аналогичен для членства в SQL. Подход, используемый для переноса данных профиля, также можно использовать в приложении с членством в SQL.
В качестве примера мы начнем с веб-приложения, созданного с помощью Visual Studio 2012, в котором используется модель поставщиков. Затем мы добавим код для управления профилями, зарегистрируем пользователя, добавим данные профиля для пользователей, перенесем схему базы данных, а затем изменим приложение для использования системы идентификации для управления пользователями и ролями. В качестве теста миграции пользователи, созданные с помощью универсальные поставщики, должны иметь возможность входа, а новые пользователи должны иметь возможность регистрироваться.
Примечание
Полный пример можно найти на странице https://github.com/suhasj/UniversalProviders-Identity-Migrations.
Сводка по переносу данных профиля
Прежде чем приступить к миграции, давайте рассмотрим процесс хранения данных профиля в модели поставщиков. Данные профиля для пользователей приложений можно хранить несколькими способами, наиболее распространенными из которых являются встроенные поставщики профилей, поставляемые вместе с универсальные поставщики. Шаги будут включать в себя
- Добавьте класс со свойствами, используемыми для хранения данных профиля.
- Добавьте класс, расширяющий "ProfileBase" и реализующий методы для получения указанных выше данных профиля для пользователя.
- Включите использование поставщиков профилей по умолчанию в файле web.config и определите класс, объявленный на шаге 2, для использования при доступе к данным профиля.
Сведения о профиле хранятся в виде сериализованных xml-данных и двоичных данных в таблице Profiles в базе данных.
После переноса приложения для использования новой системы удостоверений ASP.NET данные профиля десериализируются и сохраняются в качестве свойств в классе пользователя. Затем каждое свойство можно сопоставить со столбцами в пользовательской таблице. Преимущество заключается в том, что над свойствами можно работать напрямую с помощью класса пользователя, а также не требуется каждый раз сериализовать или десериализовать данные при доступе к ним.
Приступая к работе
Создайте новое приложение веб-формы ASP.NET 4.5 в Visual Studio 2012. В текущем примере используется шаблон веб-формы, но можно также использовать приложение MVC.
Создание папки Models для хранения сведений профиля
Например, давайте храним дату рождения, город, рост и вес пользователя в профиле. Высота и вес хранятся в виде пользовательского класса с именем "PersonalStats". Чтобы сохранить и получить профиль, нам нужен класс, расширяющий ProfileBase. Давайте создадим класс AppProfile для получения и хранения сведений профиля.
public class ProfileInfo { public ProfileInfo() { UserStats = new PersonalStats(); } public DateTime? DateOfBirth { get; set; } public PersonalStats UserStats { get; set; } public string City { get; set; } } public class PersonalStats { public int? Weight { get; set; } public int? Height { get; set; } } public class AppProfile : ProfileBase { public ProfileInfo ProfileInfo { get { return (ProfileInfo)GetPropertyValue("ProfileInfo"); } } public static AppProfile GetProfile() { return (AppProfile)HttpContext.Current.Profile; } public static AppProfile GetProfile(string userName) { return (AppProfile)Create(userName); } }
Включите профиль в файлеweb.config . Введите имя класса, который будет использоваться для хранения и извлечения сведений о пользователе, созданных на шаге 3.
<profile defaultProvider="DefaultProfileProvider" enabled="true" inherits="UniversalProviders_ProfileMigrations.Models.AppProfile"> <providers> ..... </providers> </profile>
Добавьте страницу веб-форм в папку "Учетная запись", чтобы получить данные профиля от пользователя и сохранить их. Щелкните правой кнопкой мыши проект и выберите "Добавить новый элемент". Добавьте новую страницу веб-форм с master страницей AddProfileData.aspx. Скопируйте следующую команду в разделе MainContent:
<h2> Add Profile Data for <%# User.Identity.Name %></h2> <asp:Label Text="" ID="Result" runat="server" /> <div> Date of Birth: <asp:TextBox runat="server" ID="DateOfBirth"/> </div> <div> Weight: <asp:TextBox runat="server" ID="Weight"/> </div> <div> Height: <asp:TextBox runat="server" ID="Height"/> </div> <div> City: <asp:TextBox runat="server" ID="City"/> </div> <div> <asp:Button Text="Add Profile" ID="Add" OnClick="Add_Click" runat="server" /> </div>
Добавьте следующий код в код программной части:
protected void Add_Click(object sender, EventArgs e) { AppProfile profile = AppProfile.GetProfile(User.Identity.Name); profile.ProfileInfo.DateOfBirth = DateTime.Parse(DateOfBirth.Text); profile.ProfileInfo.UserStats.Weight = Int32.Parse(Weight.Text); profile.ProfileInfo.UserStats.Height = Int32.Parse(Height.Text); profile.ProfileInfo.City = City.Text; profile.Save(); }
Добавьте пространство имен, в котором определен класс AppProfile, чтобы удалить ошибки компиляции.
Запустите приложение и создайте нового пользователя с именем пользователя olduser. Перейдите на страницу AddProfileData и добавьте сведения о профиле пользователя.
Вы можете убедиться, что данные хранятся в виде сериализованного XML-файла в таблице "Профили", с помощью окна Серверная Обозреватель. В Visual Studio в меню "Вид" выберите "Серверная Обозреватель". Должно быть подключение к данным для базы данных, определенной в файлеweb.config . При выборе подключения к данным отображаются различные подкатегории. Разверните "Таблицы", чтобы отобразить различные таблицы в базе данных, а затем щелкните правой кнопкой мыши "Профили" и выберите "Показать данные таблицы", чтобы просмотреть данные профиля, хранящиеся в таблице Profiles.
Перенос схемы базы данных
Чтобы существующая база данных работала с системой удостоверений, необходимо обновить схему в базе данных Identity для поддержки полей, добавленных в исходную базу данных. Это можно сделать с помощью скриптов SQL для создания таблиц и копирования существующих сведений. В окне Server Обозреватель разверните defaultConnection, чтобы отобразить таблицы. Щелкните правой кнопкой мыши Таблицы и выберите "Новый запрос".
Вставьте скрипт SQL из https://raw.github.com/suhasj/UniversalProviders-Identity-Migrations/master/Migration.txt и запустите его. Если параметр DefaultConnection обновлен, мы видим, что добавлены новые таблицы. Вы можете проверка данные в таблицах, чтобы убедиться, что информация была перенесена.
Перенос приложения для использования ASP.NET Identity
Установите пакеты NuGet, необходимые для ASP.NET Identity:
- Microsoft.AspNet.Identity.EntityFramework
- Microsoft.AspNet.Identity.Owin
- Microsoft.Owin.Host.SystemWeb
- Microsoft.Owin.Security.Facebook
- Microsoft.Owin.Security.Google
- Microsoft.Owin.Security.MicrosoftAccount
- Microsoft.Owin.Security.Twitter
Дополнительные сведения об управлении пакетами NuGet можно найти здесь.
Для работы с существующими данными в таблице необходимо создать классы моделей, которые сопоставляются с таблицами и подключить их в системе удостоверений. В рамках контракта Identity классы моделей должны либо реализовывать интерфейсы, определенные в библиотеке DLL Identity.Core, либо расширять существующую реализацию этих интерфейсов, доступных в Microsoft.AspNet.Identity.EntityFramework. Мы будем использовать существующие классы для роли, имен входа пользователей и утверждений пользователей. Для нашего примера необходимо использовать пользовательского пользователя. Щелкните проект правой кнопкой мыши и создайте папку IdentityModels. Добавьте новый класс User, как показано ниже:
using Microsoft.AspNet.Identity.EntityFramework; using System; using System.Collections.Generic; using System.Linq; using System.Web; using UniversalProviders_ProfileMigrations.Models; namespace UniversalProviders_Identity_Migrations { public class User : IdentityUser { public User() { CreateDate = DateTime.UtcNow; IsApproved = false; LastLoginDate = DateTime.UtcNow; LastActivityDate = DateTime.UtcNow; LastPasswordChangedDate = DateTime.UtcNow; Profile = new ProfileInfo(); } public System.Guid ApplicationId { get; set; } public bool IsAnonymous { get; set; } public System.DateTime? LastActivityDate { get; set; } public string Email { get; set; } public string PasswordQuestion { get; set; } public string PasswordAnswer { get; set; } public bool IsApproved { get; set; } public bool IsLockedOut { get; set; } public System.DateTime? CreateDate { get; set; } public System.DateTime? LastLoginDate { get; set; } public System.DateTime? LastPasswordChangedDate { get; set; } public System.DateTime? LastLockoutDate { get; set; } public int FailedPasswordAttemptCount { get; set; } public System.DateTime? FailedPasswordAttemptWindowStart { get; set; } public int FailedPasswordAnswerAttemptCount { get; set; } public System.DateTime? FailedPasswordAnswerAttemptWindowStart { get; set; } public string Comment { get; set; } public ProfileInfo Profile { get; set; } } }
Обратите внимание, что ProfileInfo теперь является свойством класса пользователя. Поэтому мы можем использовать класс пользователя для непосредственной работы с данными профиля.
Скопируйте файлы в папках IdentityModels и IdentityAccount из источника загрузки ( https://github.com/suhasj/UniversalProviders-Identity-Migrations/tree/master/UniversalProviders-Identity-Migrations ). Они имеют оставшиеся классы моделей и новые страницы, необходимые для управления пользователями и ролями с помощью API ASP.NET Identity. Используемый подход аналогичен членству в SQL, и подробное объяснение можно найти здесь.
Некоторые команды не поддерживаются, если приложение использует SQLite в качестве хранилища данных удостоверений. Из-за ограничений в ядре СУБД
Alter
команды вызывают следующее исключение:"System.NotSupportedException: SQLite не поддерживает эту операцию миграции".
В качестве обходного решения выполните миграцию Code First в базе данных, чтобы изменить таблицы.
Копирование данных профиля в новые таблицы
Как упоминалось ранее, необходимо выполнить десериализацию xml-данных в таблицах Profiles и сохранить их в столбцах таблицы AspNetUsers. Новые столбцы были созданы в таблице users на предыдущем шаге, поэтому осталось только заполнить эти столбцы необходимыми данными. Для этого мы будем использовать консольное приложение, которое запускается один раз для заполнения только что созданных столбцов в таблице users.
Создайте консольное приложение в выходе из решения.
Установите последнюю версию пакета Entity Framework.
Добавьте созданное выше веб-приложение в качестве ссылки на консольное приложение. Для этого щелкните правой кнопкой мыши проект, затем "Добавить ссылки", затем Решение, а затем щелкните проект и нажмите кнопку ОК.
Скопируйте приведенный ниже код в класс Program.cs. Эта логика считывает данные профиля для каждого пользователя, сериализует их как объект ProfileInfo и сохраняет обратно в базу данных.
public class Program { var dbContext = new ApplicationDbContext(); foreach (var profile in dbContext.Profiles) { var stringId = profile.UserId.ToString(); var user = dbContext.Users.Where(x => x.Id == stringId).FirstOrDefault(); Console.WriteLine("Adding Profile for user:" + user.UserName); var serializer = new XmlSerializer(typeof(ProfileInfo)); var stringReader = new StringReader(profile.PropertyValueStrings); var profileData = serializer.Deserialize(stringReader) as ProfileInfo; if (profileData == null) { Console.WriteLine("Profile data deserialization error for user:" + user.UserName); } else { user.Profile = profileData; } } dbContext.SaveChanges(); }
Некоторые из используемых моделей определяются в папке IdentityModels проекта веб-приложения, поэтому необходимо включить соответствующие пространства имен.
Приведенный выше код работает с файлом базы данных в папке App_Data проекта веб-приложения, созданного на предыдущих шагах. Чтобы сослаться на это, обновите строку подключения в файле app.config консольного приложения, указав строку подключения в web.config веб-приложения. Также укажите полный физический путь в свойстве AttachDbFilename.
Откройте командную строку и перейдите в папку bin указанного выше консольного приложения. Запустите исполняемый файл и просмотрите выходные данные журнала, как показано на следующем рисунке.
Откройте таблицу AspNetUsers в Обозреватель сервера и проверьте данные в новых столбцах, которые содержат свойства. Они должны быть обновлены соответствующими значениями свойств.
Проверка функциональности
Используйте только что добавленные страницы членства, реализованные с помощью ASP.NET Identity, для входа пользователя из старой базы данных. Пользователь должен иметь возможность войти в систему с теми же учетными данными. Попробуйте использовать другие функции, такие как добавление OAuth, создание нового пользователя, изменение пароля, добавление ролей, добавление пользователей к ролям и т. д.
Данные профиля для старого и нового пользователей должны быть извлечены и сохранены в таблице users. На старую таблицу больше не следует ссылаться.
Заключение
В этой статье описан процесс переноса веб-приложений, использующих модель поставщика для членства в ASP.NET identity. В этой статье также описывается перенос данных профиля для пользователей, которые будут подключены к системе удостоверений. Оставьте комментарии ниже для вопросов и проблем, возникающих при переносе приложения.
Спасибо Рику Андерсону и Роберту Мак-Мюррейу за просмотр статьи.