ASP.NET Core快速入门(第6章:ASP.NET Core MVC)--学习笔记

点击蓝字关注我们

课程链接:http://video.jessetalk.cn/course/explore

良心课程,大家一起来学习哈!

任务40:介绍

  • 1.Individual authentication 模板

  • 2.EF Core Migration

  • 3.Identity MVC:UI

  • 4.Identity MVC:EF + Identity实现

  • 5.Identity MVC:注册逻辑实现

  • 6.Identity MVC:登录逻辑实现

  • 7.Identity MVC:ReturnUrl实现

  • 8.Identity MVC:Model后端验证

  • 9.Identity MVC:Model前端验证

  • 10.Identity MVC:DbContextSeed初始化

任务41:Individual authentication 模板

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

点击Register进入注册页面

输入邮箱密码登陆

登陆成功

点击邮箱进入Manage your account

通过SSMS连接localdb

dotnet run

获取实例管道名称

& 'C:\Program Files\Microsoft SQL Server\130\Tools\Binn\SqlLocalDB.exe' info mssqllocaldb

解决PowerShell中文乱码问题,勾选UTF-8

通过实例管道名称连接localdb

任务42:EF Core Migration

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文件

生成sql脚本命令

dotnet ef migrations script

拷贝出来后可在数据库执行

任务43:Identity MVC:UI

以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">
<p>
<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>
</p>
</div>
</div>

Login.cshtml

@{
ViewData["Title"] = "Login";
}

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;

<div class="row">
<div class="col-md-4">
<p>
<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>
</p>
</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页面

任务44:Identity MVC:EF + Identity实现

在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,成功跳回主页

在数据库中查看数据

任务45:Identity MVC:注册逻辑实现

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>

启动项目

任务46:Identity MVC:登录逻辑实现

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

登陆成功

换另一个邮箱,登陆成功

任务47:Identity MVC:ReturnUrl实现

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页面

任务48:Identity MVC:Model后端验证

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

点击注册

任务49:Identity MVC:Model前端验证

将Shared文件夹中的_ValidationScriptsPartial.cshtml的jquery.validate组件添加到Login.cshtml最下面以及Register.cshtml最下面

@p Scripts
{
@await Html.PartialAsync("_ValidationScriptsPartial")
}

启动项目,直接点击登陆,注册,不会产生网络请求

任务50:Identity MVC:DbContextSeed初始化

启动的时候判断是否第一次执行,如果第一次执行则添加一个记录,比如用户账号第一次进来为管理员

在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

登陆

点“在看”给我一朵小黄花

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进程间通信的方式总结

进程间通信就是在不同进程之间传播或交换信息。 进程间通信的目的如下&#xff1a; ①数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程&#xff0c;发送的数据量在一个字节到几兆字节之间。 ②共享数据&#xff1a;多个进程想要操作共享数据&#xff0c;一个进程对…

EF Core For MySql查询中使用DateTime.Now作为查询条件的一个小问题

背景最近一直忙于手上澳洲线上项目的整体迁移和升级的准备工作&#xff0c;导致博客和公众号停更。本周终于艰难的完成了任务&#xff0c;借此机会&#xff0c;总结一下项目中遇到的一些问题。EF Core 一直是我们团队中中小型项目常用的 ORM 框架&#xff0c;在使用 SQL Server…

操作系统进程(作业)调度常见算法详解

一、进程调度的原因 在操作系统中&#xff0c;由于进程综述多于处理机&#xff0c;它们必然竞争处理机。为了充分利用计算机系统中的CPU资源&#xff0c;让计算机系统能够多快好省地完成我们让它做的各种任务&#xff0c;所以需要进行进程调度。 二、进程调度的定义 进程调度&a…

Orleans 3.0 为我们带来了什么

原文&#xff1a;https://devblogs.microsoft.com/dotnet/orleans-3-0/作者&#xff1a;Reuben Bond&#xff0c;Orleans首席软件开发工程师翻译&#xff1a;艾心这是一篇来自Orleans团队的客座文章&#xff0c;Orleans是一个使用.NET创建分布式应用的跨平台框架。获取更多信息…

进程的同步与互斥

现代操作系统采用多道程序设计机制&#xff0c;多个进程可以并发执行&#xff0c;CPU在进程之间来回切换&#xff0c;共享某些资源&#xff0c;提高了资源的利用率&#xff0c;但这也使得处理并发执行的多个进程之间的冲突和相互制约关系成为了一道难题。如果对并发进程的调度不…

缓存击穿/穿透/雪崩

缓存击穿/穿透/雪崩Intro使用缓存需要了解几个缓存问题&#xff0c;缓存击穿、缓存穿透以及缓存雪崩&#xff0c;需要了解它们产生的原因以及怎么避免&#xff0c;尤其是当你打算设计自己的缓存框架的时候需要考虑如何处理这些问题。缓存击穿一般的缓存系统&#xff0c;都是按照…

临界区、互斥量、信号量、事件的区别

四种进程或线程同步互斥的控制方法&#xff1a; 1、临界区:通过对多线程的串行化来访问公共资源或一段代码&#xff0c;速度快&#xff0c;适合控制数据访问。 2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 3、信号量:为控制一个具有有限数量用户资源而设计。 4…

99%的人不知道搜索引擎的6个技巧

点击上方“dotNET全栈开发”&#xff0c;“设为星标”加“星标★”&#xff0c;每天11.50&#xff0c;好文必达全文约900字&#xff0c;预计阅读时间1分钟今天看了一期seo优化的视频&#xff0c;其中就有这么一篇关于百度搜索的几个小技巧&#xff0c;这里整理出来&#xff0c;…

用信号量解决进程的同步与互斥

转自&#xff1a;http://www.cnblogs.com/whatbeg/p/4435286.html 现代操作系统采用多道程序设计机制&#xff0c;多个进程可以并发执行&#xff0c;CPU在进程之间来回切换&#xff0c;共享某些资源&#xff0c;提高了资源的利用率&#xff0c;但这也使得处理并发执行的多个进程…

扎心了,程序员2017到2019经历了什么?

刷爆朋友圈的2017-2019到底是什么梗&#xff1f;只剩下33天了&#xff0c;就到2020年了最后一批90后&#xff0c;马上就要30了&#xff1f;一到年底&#xff0c;就会陷入回忆和比较中近几日&#xff0c;网友开始将2017年和2019年进行对比&#xff0c;不少人晒出了自己在17年和1…

【.NETCore 3】Ids4 ║ 统一角色管理(上)

前言书接上文&#xff0c;咱们在上周&#xff0c;通过一篇《思考》 性质的文章&#xff0c;和很多小伙伴简单的讨论了下&#xff0c;如何统一同步处理角色的问题&#xff0c;众说纷纭&#xff0c;这个我一会儿会在下文详细说到&#xff0c;而且我最终也定稿方案了。所以今天咱们…

操作系统死锁详解

一、死锁的定义 死锁是两个或两个以上的进程中的每一个都在等待其中另一个进程释放资源而被封锁&#xff0c;它们都无法向前推进&#xff0c;这种现象称为死锁。 二、产生死锁的主要原因 &#xff08;1&#xff09; 因为系统资源不足。 &#xff08;2&#xff09; 进程运行推进…

.NET Core 3.0 使用Nswag生成Api文档和客户端代码

摘要在前后端分离、Restful API盛行的年代&#xff0c;完美的接口文档&#xff0c;成了交流的纽带。在项目中引入Swagger &#xff08;也称为OpenAPI&#xff09;&#xff0c;是种不错的选择&#xff0c;它可以让接口数据可视化。下文将会演示利用Nswag如何生成Api文档利用NSwa…

什么是虚拟内存?

虚拟内存是计算机系统内存管理的一种技术。 它使得应用程序认为它拥有连续的可用的内存&#xff08;一个连续完整的地址空间&#xff09;&#xff0c;而实际上&#xff0c;它通常是被分隔成多个物理内存碎片&#xff0c;还有部分暂时存储在外部磁盘存储器上&#xff0c;在需要…

深入研究 Angular 和 ASP.NET Core 3.0

本文要点&#xff1a;可以把多个 Angular 应用程序集成到 ASP.NET 网站中把 Angular 代码打包成 Web 组件是引导 Angular 应用程序的好方法可以把用 Angular 编写的 Web 组件轻松地集成到 ASP.NET 视图中把 Angular 解决方案构造成 Angular 应用程序的集合以实现更好的代码重用…

操作系统内存管理--简单、页式、段式、段页式

一、内存管理的目的和功能 内存一直是计算机系统中宝贵而又紧俏的资源&#xff0c;内存能否被有效、合理地使用&#xff0c;将直接影响到操作系统的性能。此外&#xff0c;虽然物理内存的增长现在达到了N个GB&#xff0c;但比物理内存增长还快的是程序&#xff0c;所以无论物理…

网易裁员背后,芸芸众生,相煎何急

十一月初拖家带口去了上海&#xff0c;到了著名的城隍庙参观&#xff0c;无意中看到了一个仅出现在历史书上的古老物件“西洋镜”&#xff0c;仿佛跨越百年&#xff0c;来到那个如裹脚布般冗长而乏味的古老年代&#xff0c;看到了一群有一群卑微的小民在生活的裹挟之下&#xf…

LRU和LFU的区别

一、概念介绍 LRU和LFU都是内存管理的页面置换算法。 LRU&#xff0c;即&#xff1a;最近最少使用淘汰算法&#xff08;Least Recently Used&#xff09;。LRU是淘汰最长时间没有被使用的页面。 LFU&#xff0c;即&#xff1a;最不经常使用淘汰算法&#xff08;Least Frequentl…

网速和带宽的区别

为了弄清网速和带宽直接的区别&#xff0c;我们首先需要明白两个概念&#xff1a; Byte&#xff08;字节&#xff09;和bit&#xff08;位&#xff09;。 字节是计算机中用于计算存储容量的一种计量单位&#xff0c;简称B。一个字节由8个位组成&#xff0c;即&#xff1a; 1Byt…

.NET Core on K8S 学习与实践系列文章索引 (更新至20191126)

更新记录&#xff1a;-- 2019-11-26 增加Docker容器日志系列文章近期在学习Kubernetes&#xff0c;基于之前做笔记的习惯&#xff0c;已经写了一部分文章&#xff0c;因此给自己立一个flag&#xff1a;完成这个《.NET Core on K8S学习实践》系列文章&#xff01;这个系列会持续…