课程链接:http://video.jessetalk.cn/course/explore
良心课程,大家一起来学习哈!
dotnet new mvc --help
Options:
-au|--auth The type of authentication to use
None - No authentication
Individual - Individual authentication
IndividualB2C - Individual authentication with Azure AD B2C
SingleOrg - Organizational authentication for a single tenant
MultiOrg - Organizational authentication for multiple tenants
Windows - Windows authentication
Default: None
-uld|--use-local-db Whether to use LocalDB instead of SQLite. This option only applies if --auth Individual or --auth IndividualB2C is specified.
bool - Optional
Default: false / (*) true
解决VScode终端乱码
chcp 65001
dotnet new mvc -au Individual -uld --name IdentitySample
默认创建localdb,Identity
appsettings.json
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-IdentitySample-40453418-3C8F-43D7-94F8-BD1BD20BDD96;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Startup.cs
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
初始化数据库,根据Data/Migrations文件夹下的数据库文件创建更新数据库
dotnet ef database update
报错:
无法执行,因为找不到指定的命令或文件。
可能的原因包括:
*你拼错了内置的 dotnet 命令。
*你打算执行 .NET Core 程序,但 dotnet-ef 不存在。
*你打算运行全局工具,但在路径上找不到名称前缀为 dotnet 的可执行文件。
在stackoverflow找到解决方法:
https://stackoverflow.com/questions/45091909/dotnet-ef-database-update-no-executable-found-matching-command-dotnet-ef?r=SearchResults
在csproj文件的ItemGroup中添加引用
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0-preview2-final" />
dotnet restore
dotnet ef database update
dotnet run
访问https://localhost:5001
dotnet run
获取实例管道名称
& 'C:\Program Files\Microsoft SQL Server\130\Tools\Binn\SqlLocalDB.exe' info mssqllocaldb
解决PowerShell中文乱码问题,勾选UTF-8
通过实例管道名称连接localdb
dotnet ef migrations add InitialCreat
dotnet ef database update
dotnet ef migrations remove
dotnet ef database update LastGoodMigration
dotnet ef migrations scrept
添加列之前
在Models文件夹下新增ApplicationUser.cs
using System;
using Microsoft.AspNetCore.Identity;
namespace IdentitySample.Models
{
public class ApplicationUser : IdentityUser
{
public string NewColumn{get;set;}
}
}
dotnet ef migrations add AddNewColumn
自动生成文件
dotnet ef database update
执行成功后刷新数据库,可以看到数据库中多了一列NewColumn
在ApplicationUser.cs中新增Address
public string Address{get;set;}
dotnet ef migrations add AddAddress
dotnet ef database update
执行成功后刷新数据库,可以看到数据库中多了一列Address
dotnet ef database update AddNewColumn
执行成功后刷新数据库,可以看到数据库中Address不见了
dotnet ef migrations remove
执行成功后移除AddAddress.cs以及AddAddress.Designer.cs文件
dotnet ef migrations script
拷贝出来后可在数据库执行
以MvcCookieAuthSample项目为基础,通过ef core以及Identity实现注册登陆UI整个过程
AccountController.cs新增Register,Login
public IActionResult Register()
{
return View();
}
public IActionResult Login()
{
return View();
}
public IActionResult MakeLogin()
在Views文件夹下新建Account文件夹,在Account文件夹下新增Register.cshtml以及Login.cshtml
Register.cshtml
@{
ViewData["Title"] = "Register";
}
@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p>
<div class="row">
<div class="col-md-4">
<form id="registerForm" method="post" novalidate="novalidate">
<h4>Create a new account.</h4>
<hr>
<div class="form-group">
<label asp-for="Input_Email">Email</label>
<input asp-for="Input_Email" class="form-control" type="email">
</div>
<div class="form-group">
<label asp-for="Input_Password">Password</label>
<input asp-for="Input_Password" class="form-control" type="password">
</div>
<div class="form-group">
<label asp-for="Input_ConfirmPassword">Confirm password</label>
<input asp-for="Input_ConfirmPassword" class="form-control" type="password">
</div>
<button id="registerSubmit" type="submit" class="btn btn-primary">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8HHmKd6uCEtOsAkKHNEfx50wHX7kOnWmAzVSUOOnXiiks-t4chi5eY9XThPYt70X-X6qtCV55TTEowbXbnCAW-91KSw1XVqXqBd48bMdGuVeGHFeZU61gw9jtNtAUDP7gCYnN9J_9d6o5w9sL12jw1E"></form>
</div>
<div class="col-md-6 col-md-offset-2">
<section>
<h4>Use another service to register.</h4>
<hr>
<div>
<p>
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
</section>
</div>
</div>
Login.cshtml
@{
ViewData["Title"] = "Login";
}
@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;
<div class="row">
<div class="col-md-4">
<section>
<form id="account" method="post" novalidate="novalidate">
<h4>Use a local account to log in.</h4>
<hr>
<div class="form-group">
<label asp-for="Input_Email">Email</label>
<input asp-for="Input_Email" class="form-control" type="email">
</div>
<div class="form-group">
<label asp-for="Input_Password">Password</label>
<input asp-for="Input_Password" class="form-control" type="password">
</div>
<div class="form-group">
<button id="login-submit" type="submit" class="btn btn-primary">Log in</button>
</div>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8HHmKd6uCEtOsAkKHNEfx514_36YMa9FLgbR-vliay5DWvu05X4yejzvlNz6ULPfevJg9b12mlIjiWYP9ifLswnUdt43dzUmlvJzsanhL7RHmQMDAwrKRRTJWtaHJ4qbHUNyldkz95mHRrvivNTez9I"><input name="Input.RememberMe" type="hidden" value="false"></form>
</section>
</div>
</div>
新建ViewModels文件夹,在ViewModels文件夹下新建RegisterViewModel.cs
RegisterViewModel.cs
namespace MvcCookieAuthSample.ViewModels
{
public class RegisterViewModel
{
public string Input_Email{get;set;}
public string Input_Password{get;set;}
public string Input_ConfirmPassword{get;set;}
}
}
在Views/Shared目录下的_Layout.cshtml中增加Register以及Login
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
<li><a asp-area="" asp-controller="Account" asp-action="Login">Login</a></li>
</ul>
</div>
dotnet run
点击进入Register以及Login页面
在Models文件夹新增ApplicationUser.cs以及ApplicationUserRole.cs
ApplicationUser.cs
using Microsoft.AspNetCore.Identity;
namespace MvcCookieAuthSample.Models
{
// 默认主键GUID,可通过泛型修改
public class ApplicationUser : IdentityUser<int>
{
}
}
ApplicationUserRole.cs
using Microsoft.AspNetCore.Identity;
namespace MvcCookieAuthSample.Models
{
// 默认主键GUID,可通过泛型修改
public class ApplicationUserRole : IdentityRole<int>
{
}
}
新建Data文件夹,在Data文件夹下新建ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using MvcCookieAuthSample.Models;
namespace MvcCookieAuthSample.Data
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationUserRole, int>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
}
在appsettings.json中添加ConnectionStrings
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-IdentitySample-81D77053-883E-44D8-A94D-195B9C54C2B6;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
Startup.cs添加以下内容
using MvcCookieAuthSample.Data;
using Microsoft.EntityFrameworkCore;
using MvcCookieAuthSample.Models;
using Microsoft.AspNetCore.Identity;
public void ConfigureServices(IServiceCollection services)
{
// services.Configure<CookiePolicyOptions>(options =>
// {
// // This lambda determines whether user consent for non-essential cookies is needed for a given request.
// options.CheckConsentNeeded = context => true;
// options.MinimumSameSitePolicy = SameSiteMode.None;
// });
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});
services.AddIdentity<ApplicationUser, ApplicationUserRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Addmvc之前AddAuthentication,AddCookie
// services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
// .AddCookie();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/Login";
});
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
});
//services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc();
}
AccountController.cs添加以下内容
using MvcCookieAuthSample.ViewModels;
using Microsoft.AspNetCore.Identity;
//[Authorize]
public class AccountController : Controller
private UserManager<ApplicationUser> _userManager;
private SignInManager<ApplicationUser> _signInManager;
public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var identityUser = new ApplicationUser
{
Email = registerViewModel.Input_Email,
UserName = registerViewModel.Input_Email,
NormalizedEmail = registerViewModel.Input_Email
};
var identityResult = await _userManager.CreateAsync(identityUser, registerViewModel.Input_Password);
if (identityResult.Succeeded)
{
return RedirectToAction("Index", "Home");
}
return View();
}
添加nuget包:Microsoft.EntityFrameworkCore.Tools
VSCode报错:Versioning information could not be retrieved from the NuGet package repository. Please try again later.
使用Visual Studio添加nuget包
dotnet ef migrations add VSInit
dotnet ef database update
报错:There is already an object named 'AspNetRoles' in the database.
删除之前的数据库实例
dotnet ef migrations add VSInit
dotnet ef database update
主键为int
dotnet run
点击Register,成功跳回主页
在数据库中查看数据
AccountController.cs
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var identityUser = new ApplicationUser
{
Email = registerViewModel.Input_Email,
UserName = registerViewModel.Input_Email,
NormalizedEmail = registerViewModel.Input_Email
};
var identityResult = await _userManager.CreateAsync(identityUser, registerViewModel.Input_Password);
if (identityResult.Succeeded)
{
// 封装了下面MakeLogin()方法中的HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));
await _signInManager.SignInAsync(identityUser, new AuthenticationProperties {IsPersistent = true});
return RedirectToAction("Index", "Home");
}
return View();
}
启动项目,重新注册一个
看到Cookie,登陆成功
修改Views/Shared文件夹下的_Layout.cshtml
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
@if (User.Identity.IsAuthenticated)
{
<li>Welcome, @User.Identity.Name, <a asp-area="" asp-controller="Account" asp-action="Logout">Logout</a></li>
}
else
{
<li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
<li><a asp-area="" asp-controller="Account" asp-action="Login">Login</a></li>
}
</ul>
</div>
启动项目
AccountController.cs
[HttpPost]
public async Task<IActionResult> Login(RegisterViewModel loginViewModel)
{
var user = await _userManager.FindByEmailAsync(loginViewModel.Input_Email);
if (user == null)
{
}
await _signInManager.SignInAsync(user, new AuthenticationProperties {IsPersistent = true});
return RedirectToAction("Index", "Home");
}
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return RedirectToAction("Index", "Home");
}
//public IActionResult Logout()
//{
// HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// return Ok();
//}
_Layout.cshtml
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
@if (User.Identity.IsAuthenticated)
{
<form asp-action="Logout" asp-controller="Account" method="post">
<ul class="nav navbar-nav navbar-right">
<li><a title="Welcome" asp-controller="Admin" asp-action="Index"> @User.Identity.Name, </a></li>
<li><button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button></li>
</ul>
</form>
}
else
{
<ul class="nav navbar-nav navbar-right">
<li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
<li><a asp-area="" asp-controller="Account" asp-action="Login">Login</a></li>
</ul>
}
</div>
Views/Account文件夹中的Login.cshtml
<form id="account" method="post" asp-controller="Account" asp-action="Login" novalidate="novalidate">
启动项目
点击Log out,回到主页
点击Login
登陆成功
换另一个邮箱,登陆成功
AccountController.cs
private IActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
return Redirect(returnUrl);
return RedirectToAction(nameof(HomeController.Index), "Home");
}
public IActionResult Register(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
var identityUser = new ApplicationUser
{
Email = registerViewModel.Input_Email,
UserName = registerViewModel.Input_Email,
NormalizedEmail = registerViewModel.Input_Email
};
var identityResult = await _userManager.CreateAsync(identityUser, registerViewModel.Input_Password);
if (identityResult.Succeeded)
{
// 封装了下面MakeLogin()方法中的HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));
await _signInManager.SignInAsync(identityUser, new AuthenticationProperties {IsPersistent = true});
//return RedirectToAction("Index", "Home");
return RedirectToLocal(returnUrl);
}
return View();
}
public IActionResult Login(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
public async Task<IActionResult> Login(RegisterViewModel loginViewModel, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
var user = await _userManager.FindByEmailAsync(loginViewModel.Input_Email);
if (user == null)
{
}
await _signInManager.SignInAsync(user, new AuthenticationProperties {IsPersistent = true});
//return RedirectToAction("Index", "Home");
return RedirectToLocal(returnUrl);
}
Register.cshtml
<form id="registerForm" method="post" asp-route-returnUrl="@ViewData["ReturnUrl"]" novalidate="novalidate">
Login.cshtml
<form id="account" method="post" asp-controller="Account" asp-action="Login" asp-route-returnUrl="@ViewData["ReturnUrl"]" novalidate="novalidate">
启动项目,访问:https://localhost:44387/admin
点击Log out,再次访问:https://localhost:44387/admin,跳转到登陆界面
登陆之后直接到admin页面
RegisterViewModel.cs
using System.ComponentModel.DataAnnotations;
namespace MvcCookieAuthSample.ViewModels
{
public class RegisterViewModel
{
[Required]
[DataType(DataType.EmailAddress)]
public string Input_Email{get;set;}
[Required]
[DataType(DataType.Password)]
public string Input_Password{get;set;}
[Required]
[DataType(DataType.Password)]
public string Input_ConfirmPassword{get;set;}
}
}
在ViewModels文件夹下新增LoginViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace MvcCookieAuthSample.ViewModels
{
public class LoginViewModel
{
[Required]
[DataType(DataType.EmailAddress)]
public string Input_Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Input_Password { get; set; }
}
}
AccountController.cs第一个参数类型由RegisterViewModel修改为LoginViewModel
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl = null)
{
if (ModelState.IsValid)
{
ViewData["ReturnUrl"] = returnUrl;
var user = await _userManager.FindByEmailAsync(loginViewModel.Input_Email);
if (user == null)
{
}
await _signInManager.SignInAsync(user, new AuthenticationProperties { IsPersistent = true });
//return RedirectToAction("Index", "Home");
return RedirectToLocal(returnUrl);
}
return View();
}
Login.cshtml
<div class="form-group">
<label asp-for="Input_Email">Email</label>
<input asp-for="Input_Email" class="form-control" type="email">
<span asp-validation-for="Input_Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input_Password">Password</label>
<input asp-for="Input_Password" class="form-control" type="password">
<span asp-validation-for="Input_Password" class="text-danger"></span>
</div>
启动项目,不输入邮箱密码直接点击登陆
Register.cshtml
<div class="form-group">
<label asp-for="Input_Email">Email</label>
<input asp-for="Input_Email" class="form-control" type="email">
<span asp-validation-for="Input_Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input_Password">Password</label>
<input asp-for="Input_Password" class="form-control" type="password">
<span asp-validation-for="Input_Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input_ConfirmPassword">Confirm password</label>
<input asp-for="Input_ConfirmPassword" class="form-control" type="password">
<span asp-validation-for="Input_ConfirmPassword" class="text-danger"></span>
</div>
AccountController.cs
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel, string returnUrl = null)
{
if (ModelState.IsValid)
{
ViewData["ReturnUrl"] = returnUrl;
var identityUser = new ApplicationUser
{
Email = registerViewModel.Input_Email,
UserName = registerViewModel.Input_Email,
NormalizedEmail = registerViewModel.Input_Email
};
var identityResult = await _userManager.CreateAsync(identityUser, registerViewModel.Input_Password);
if (identityResult.Succeeded)
{
// 封装了下面MakeLogin()方法中的HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));
await _signInManager.SignInAsync(identityUser, new AuthenticationProperties { IsPersistent = true });
//return RedirectToAction("Index", "Home");
return RedirectToLocal(returnUrl);
}
}
return View();
}
启动项目,直接点击注册
Startup.cs
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 12;
});
Register.cshtml添加text-danger
<h4>Create a new account.</h4>
<hr>
<div class="text-danger" asp-validation-summary="All"></div>
AccountController.cs
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel, string returnUrl = null)
{
if (ModelState.IsValid)
{
ViewData["ReturnUrl"] = returnUrl;
var identityUser = new ApplicationUser
{
Email = registerViewModel.Input_Email,
UserName = registerViewModel.Input_Email,
NormalizedEmail = registerViewModel.Input_Email
};
var identityResult = await _userManager.CreateAsync(identityUser, registerViewModel.Input_Password);
if (identityResult.Succeeded)
{
// 封装了下面MakeLogin()方法中的HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));
await _signInManager.SignInAsync(identityUser, new AuthenticationProperties { IsPersistent = true });
//return RedirectToAction("Index", "Home");
return RedirectToLocal(returnUrl);
}
else
{
AddErrors(identityResult);
}
}
return View();
}
启动项目,随便输入密码123
点击注册
将Shared文件夹中的_ValidationScriptsPartial.cshtml的jquery.validate组件添加到Login.cshtml最下面以及Register.cshtml最下面
@section Scripts
{
@await Html.PartialAsync("_ValidationScriptsPartial")
}
启动项目,直接点击登陆,注册,不会产生网络请求
启动的时候判断是否第一次执行,如果第一次执行则添加一个记录,比如用户账号第一次进来为管理员
在Data文件夹新增ApplicationDbContextSeed.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using MvcCookieAuthSample.Models;
using Microsoft.Extensions.DependencyInjection;
namespace MvcCookieAuthSample.Data
{
public class ApplicationDbContextSeed
{
private UserManager<ApplicationUser> _userManager;
public async Task SeedSync(ApplicationDbContext context, IServiceProvider services)
{
if (!context.Users.Any())
{
_userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
var defaultUser = new ApplicationUser
{
UserName = "Administrator",
Email = "mingsonzheng003@outlook.com",
NormalizedUserName = "admin"
};
var result = await _userManager.CreateAsync(defaultUser, "Password$123");
if (!result.Succeeded)
throw new Exception("初始默认用户失败");
}
}
}
}
在Data文件夹新增扩展方法调用ApplicationDbContextSeed
WebHostMigrationExtensions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace MvcCookieAuthSample.Data
{
public static class WebHostMigrationExtensions
{
public static IWebHost MigrateDbContext<TContext>(this IWebHost host, Action<TContext, IServiceProvider> sedder)
where TContext : DbContext
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var logger = services.GetRequiredService<ILogger<TContext>>();
var context = services.GetService<TContext>();
try
{
context.Database.Migrate();
sedder(context, services);
logger.LogInformation($"执行DBContext { typeof(TContext).Name } seed执行成功");
}
catch (Exception ex)
{
logger.LogInformation($"执行DBContext { typeof(TContext).Name } seed执行失败");
}
}
return host;
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MvcCookieAuthSample.Data;
namespace MvcCookieAuthSample
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build()
.MigrateDbContext<ApplicationDbContext>((context, services) =>
{
new ApplicationDbContextSeed().SeedSync(context, services)
.Wait();
})
.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
删除数据库
控制台方式启动项目,先进行数据库初始化,再启动WebHost
数据库自动插入数据
输入邮箱,密码:Password$123
登陆