Переопределение системы AspNet Identity

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

Ранее мы рассмотрели основные моменты AspNet Identity и то, как ее использовать. Однако встроенная система не всегда в полной мере удовлетворяет нуждам разработчиков. И может потребоваться переопределить ее: добавить новые поля к модели, добавить новые таблицы и т.д. Рассмотрим, как переопределять базовый механизм AspNet Identity.

Как мы увидели в прошлых темах, при использовании AspNet Identity по умолчанию создается база данных со стандартным набором таблиц. Для взаимодействия с базой данных в проекте определен контекст данных ApplicationDbContext, который можно найти в файле IdentityModels.cs в папке Models:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

Кроме того, здесь также описывается класс пользователей ApplicationUser, который наследует всю логику от IdentityUser. При регистрации контекст данных заносит в бд логин и хеш пароля пользователя. Однако, что если мы хотим определить еще ряд полей, например, возраст и т.д.? Изменим модели в файле IdentityModels.cs следующим образом:

public class ApplicationUser : IdentityUser
{
	public int Age { get; set; } // добавляем свойство Age
	
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}
// добавляем модель Book
public class Book
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Author { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
	public DbSet<Book> Books { get; set; }
	
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

Во-первых, мы добавили новое свойство в класс ApplicationUser. Во-вторых, мы также добавили новый класс Book и свойство Books в контекст данных.

Поскольку у нас изменился контекст данных и модель пользователя, то созданная ранее база данных уже не будет отражать наши модели, и ее надо перестроить. В этом нам помогут миграции. Итак, внизу Visual Studio в окне Package Manager Console введем команду: enable-migrations и нажмем Enter:

В результате выполнения этой команды Visual Studio создаст в проекте папку Migrations, в которой можно найти файл Configuration.cs. Этот файл содержит объявление одноименного класса Configuration, который устанавливает настройки конфигурации:

namespace CustomIdentity.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<CustomIdentity.Models.ApplicationDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            ContextKey = "CustomIdentity.Models.ApplicationDbContext";
        }

        protected override void Seed(CustomIdentity.Models.ApplicationDbContext context)
        {
        }
    }
}

В методе Seed можно проинициализировать базу данных начальными данными. Теперь нам надо создать саму миграцию. Там же в консоли Package Manager Console введем команду:

PM> Add-Migration "DataMigration"

После этого Visual Studio автоматически сгенерирует класс миграции:

namespace CustomIdentity.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class DataMigration : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Books",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Name = c.String(),
                        Author = c.String(),
                    })
                .PrimaryKey(t => t.Id);
            
            AddColumn("dbo.AspNetUsers", "Age", c => c.Int(nullable: false));
        }
        
        public override void Down()
        {
            DropColumn("dbo.AspNetUsers", "Age");
            DropTable("dbo.Books");
        }
    }
}

И чтобы выполнить миграцию, применим этот класс, набрав в той же консоли команду:

PM> Update-Database

После этого, если мы посмотрим на состав базы данных, то увидим, что к ней были применены изменения в соответствии с выполненной миграцией:

Так как у нас появилось новое свойство в ApplicationUser, изменим модель регистрации в файле AccountViewModels.cs, который находится в папке Models:

public class RegisterViewModel
    {
        [Required]
        public string Email { get; set; }

        [Required]
        public int Age { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }

И также добавим в представление для регистрации Register.cshtml пару новых полей:

<div class="form-group">
    @Html.LabelFor(m => m.Age, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.Age, new { @class = "form-control" })
    </div>
</div>

Внешний вид страницы регистрации в итоге будет выглядеть так:

И изменим код добавления нового пользователя в методе Register контроллера AccountController. Сейчас он выглядит так:

var user = new ApplicationUser { UserName = model.Email, Email = model.Email };

изменим его на:

var user = new ApplicationUser { UserName = model.Email, Email = model.Email, Age=model.Age };

Теперь мы можем добавлять новых пользователей, указывая у них дополнительные свойства. И также при желании сделать функционал по добавлению объектов Book в таблицу Books или создать новые свойства моделей и новые таблицы.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850