菜鸟入门【ASP.NET Core】14:MVC开发:UI、 EF + Identity实现、注册实现、登陆实现

简介: 前言 之前我们进行了MVC的web页面的Cookie-based认证实现,接下来的开发我们要基于之前的MvcCookieAuthSample项目做修改。 MvcCookieAuthSample项目地址:http://www.

前言

之前我们进行了MVC的web页面的Cookie-based认证实现,接下来的开发我们要基于之前的MvcCookieAuthSample项目做修改。

MvcCookieAuthSample项目地址:http://www.cnblogs.com/wyt007/p/8128186.html

UI

我们首先在AccountController中添加两个Action

复制代码
        public IActionResult Register()        
     {
  
        return View();
        }

        public IActionResult Login()
        {
            return View();
        }
复制代码

然后在Views文件夹下新增Account文件夹并新增Register.cshtml与Login.cshtml视图,样式我们尽量从上一节的Identity视图中拷贝过来。

我们还需要新建一个ViewModels,在ViewModels中新建RegisterViewModel.cs来接收表单提交的值以及来进行强类型视图

复制代码
namespace MvcCookieAuthSample.ViewModels
{
    public class RegisterViewModel
    {
        //邮箱
        public string Email { get; set; }
        //密码
        public string Password { get; set; }
        //确认密码
        public string ConfirmedPassword { get; set; }
    }
}
复制代码

Register.cshtml代码(只保留部分拷贝过来的内容,并加入强类型视图引用):

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

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;

<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>

<div class="row">
<div class="col-md-4">
<form method="post">
<h4>Create a new account.</h4>
<hr />
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" />
</div>
<div class="form-group">
<label asp-for="ConfirmedPassword"></label>
<input asp-for="ConfirmedPassword" class="form-control" />
</div>
<button type="submit" class="btn btn-default">Register</button>
</form>
</div>
</div>

 

Login.cshtml代码(只保留部分拷贝过来的内容,并加入强类型视图引用):

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

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;

<div class="row">
<div class="col-md-4">
<section>
<form method="post">
<h4>Use a local account to log in.</h4>
<hr />

<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
</div>

<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" type="password" class="form-control" />
</div>

<div class="form-group">
<button type="submit" class="btn btn-default">Log in</button>
</div>

</form>
</section>
</div>
</div>

 

然后在_Layout.cshtml中添加导航代码:

<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">Log in</a></li>
</ul>

然后运行网站,UI已经实现

 

EF + Identity实现

EF实现

首先我们添加一个Data文件夹,由于VSCode的代码提示不是很好,接下来我们用VS2017开发。

我们首先在Models文件夹下面新建ApplicationUser.cs与ApplicationUserRole.cs

ApplicationUser.cs代码:

复制代码
using Microsoft.AspNetCore.Identity;

namespace MvcCookieAuthSample.Models
{
    public class ApplicationUser:IdentityUser<int>//不加int的话是默认主键为guid
    {
    }
}
复制代码

ApplicationUserRole.cs代码:

复制代码
using Microsoft.AspNetCore.Identity;

namespace MvcCookieAuthSample.Models
{
    public class ApplicationUserRole: IdentityRole<int>//不加int的话是默认主键为guid
    {
    }
}
复制代码

然后在Data文件夹下新建一个ApplicationDbContext.cs类,使它继承IdentityDbContext

复制代码
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using MvcCookieAuthSample.Models;

namespace MvcCookieAuthSample.Data
{
    public class ApplicationDbContext:IdentityDbContext<ApplicationUser, ApplicationUserRole,int>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options):base(options)
        {

        }
    }
}
复制代码

然后我们需要在Startup.cs添加EF的注册进来

//使用配置ApplicationDbContext使用sqlserver数据库,并配置数据库连接字符串
services.AddDbContext<ApplicationDbContext>(options=> {
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});

然后我们需要在appsettings.json中配置数据库连接字符串

"ConnectionStrings": {
  "DefaultConnection": "Server=192.168.1.184;Database=aspnet-IdentitySample-9A22BB3E-8D53-4F44-B533-2EF927C959DE;Trusted_Connection=True;MultipleActiveResultSets=true;uid=sa;pwd=123456"
}

EF实现结束

Identity实现

我们需要在Startup.cs添加Identity的注册进来

//配置Identity
services.AddIdentity<ApplicationUser, ApplicationUserRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

由于默认的Identity在密码上限制比较严格,我们把它改的宽松简单一点(不设置也行)

复制代码
//修改Identity配置
services.Configure<IdentityOptions>(options =>
{
    options.Password.RequireLowercase = false;//需要小写
    options.Password.RequireNonAlphanumeric = false;//需要字母
    options.Password.RequireUppercase = false;//需要大写
});
复制代码

然后我们把认证的地址改成/Account/Login

然后我们修改AccountController,加入以下代码

复制代码
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.Email,
        UserName = registerViewModel.Email,
        NormalizedUserName = registerViewModel.Email
    };
    var identityResult=await _userManager.CreateAsync(identityUser, registerViewModel.Password);
    if (identityResult.Succeeded)
    {
        return RedirectToAction("Index", "Home");
    }

    return View();
}
复制代码

 

完整的AccountController

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MvcCookieAuthSample.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
using MvcCookieAuthSample.ViewModels;
using Microsoft.AspNetCore.Identity;

namespace MvcCookieAuthSample.Controllers
{

public class AccountController : Controller
{
private UserManager<ApplicationUser> _userManager;//创建用户的
private SignInManager<ApplicationUser> _signInManager;//用来登录的

//依赖注入
public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}


public IActionResult Register()
{
return View();
}

[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var identityUser = new ApplicationUser
{
Email = registerViewModel.Email,
UserName = registerViewModel.Email,
NormalizedUserName = registerViewModel.Email
};
var identityResult=await _userManager.CreateAsync(identityUser, registerViewModel.Password);
if (identityResult.Succeeded)
{
return RedirectToAction("Index", "Home");
}

return View();
}

public IActionResult Login()
{
return View();
}

 

//登陆
public IActionResult MakeLogin()
{
var claims=new List<Claim>(){
new Claim(ClaimTypes.Name,"wyt"),
new Claim(ClaimTypes.Role,"admin")
};

var claimIdentity= new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme);

HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));

return Ok();
}

//登出
public IActionResult Logout()
{
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

return Ok();
}
}
}

 

接下来我们重新生成一下,我们需要执行shell命令生成一下数据库,只有添加  Microsoft.EntityFrameworkCore.Tools  才会生成成功,否则会报以下错误

执行命令总是提示 未找到与命令“dotnet-ef”匹配的可执行文件,根据网上的解决办法引用 Microsoft.EntityFrameworkCore.Tools 问题依旧不能得到解决。

解决办法:

右击项目弹出菜单点击编辑***.csprog,增加如下配置。

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>

执行增加配置命令后

这时候Data文件夹下已经有新增的数据库更新配置文件了

然后我们执行更新命令,执行成功后我们就可以看到数据库表已经生成了

接下来我们运行一下网站进行注册,注册成功,已经存储进数据库

 注册实现

前面虽然可以注册了,但是我们注册完成后并没有生成Cookies信息。所以我们要在Register方法中进行登陆生成Cookies

完整的注册方法如下:

[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var identityUser = new ApplicationUser
{
Email = registerViewModel.Email,
UserName = registerViewModel.Email,
NormalizedUserName = registerViewModel.Email
};
var identityResult=await _userManager.CreateAsync(identityUser, registerViewModel.Password);
if (identityResult.Succeeded)
{
//注册完成登录生成cookies信息
await _signInManager.SignInAsync(identityUser, new AuthenticationProperties { IsPersistent = true });

return RedirectToAction("Index", "Home");
}

return View();
}

一般来说,如果用户已经注册或者登陆了,注册和登陆按钮是要隐藏的,所以我们接下来要修改_Layout.cshtml视图页面判断注册/登陆按钮是否应该隐藏

 

完整的_Layout.cshtml代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MvcCookieAuthSample</title>

<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">MvcCookieAuthSample</a>
</div>
<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">Log in</a></li>
</ul>
}


</div>
</div>
</nav>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>&copy; 2018 - MvcCookieAuthSample</p>
</footer>
</div>

<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>

@RenderSection("Scripts", required: false)
</body>
</html>

 

这时候登陆的之后的导航栏信息就有了

登陆实现

 我们接下来实现一下登陆逻辑,我们首先新建一个HttpPost的Login的Action

复制代码
[HttpPost]
public async Task<IActionResult> Login(RegisterViewModel loginViewModel)
{
    var user= await _userManager.FindByEmailAsync(loginViewModel.Email);
    if (user==null)
    {
        //异常先不写,后期统一收集
    }
    //账号密码先不做验证,需要可以自己写
    await _signInManager.SignInAsync(user, new AuthenticationProperties { IsPersistent = true });

    return RedirectToAction("Index", "Home");
}
复制代码

然后我们把原来的Logout也顺便修改一下,不能是return OK();而要跳转到首页

复制代码
//登出
public async Task<IActionResult> Logout()
{
    //HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    //return Ok();

    await _signInManager.SignOutAsync();
    return RedirectToAction("Index", "Home");
}
复制代码

 接下来我们修改一下Login.cshtml页面

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

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;

<div class="row">
<div class="col-md-4">
<section>
<form method="post" asp-controller="Account" asp-action="Login">
<h4>Use a local account to log in.</h4>
<hr />

<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
</div>

<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" type="password" class="form-control" />
</div>

<div class="form-group">
<button type="submit" class="btn btn-default">Log in</button>
</div>

</form>
</section>
</div>
</div>

接下来我们可以运行一下登陆注册,即可成功登陆后跳转到首页,注册后跳转倒是首页

相关文章
|
2月前
|
开发框架 前端开发 JavaScript
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发一
本文介绍了方舟开发框架(ArkUI)及其两种开发范式:基于ArkTS的声明式开发范式和类Web开发范式。ArkUI是用于构建HarmonyOS应用界面的UI框架,提供极简UI语法和基础设施。声明式开发范式使用ArkTS语言,以组件、动画和状态管理为核心,适合复杂团队协作;类Web开发范式采用HML、CSS、JavaScript三段式开发,适用于简单界面应用,贴近Web开发者习惯。文中还概述了两者的架构和基础能力,帮助开发者选择合适的范式进行高效开发。
84 15
|
2月前
|
编解码 前端开发 Java
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发三
本文介绍了基于声明式UI范式的图形绘制与动画效果实现方法,涵盖绘制图形、添加动画效果及常见组件说明三部分内容。在绘制图形部分,详细讲解了如何通过Circle组件为食物成分表添加圆形标签,以及使用Path组件结合SVG命令绘制自定义图形(如应用Logo)。动画效果部分则展示了如何利用animateTo实现闪屏动画,包括渐出、放大效果,并设置页面跳转;同时介绍了页面间共享元素转场动画的实现方式。最后,文章列举了声明式开发范式中的各类组件及其功能,帮助开发者快速上手构建复杂交互页面。
81 11
|
1月前
|
JavaScript 前端开发 UED
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发四
本文介绍了Web组件开发与性能优化的相关内容。在Web组件开发部分,涵盖创建组件、设置样式与属性、添加事件和方法以及场景示例,如动态播放视频。性能提升方面,推荐使用数据懒加载、条件渲染替代显隐控制、Column/Row替代Flex、设置List组件宽高及调整cachedCount减少滑动白块等方法,以优化应用性能与用户体验。
120 56
|
1月前
|
编解码 UED 开发者
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发之常见布局
本文主要介绍了自适应布局与响应式布局的相关内容。自适应布局部分涵盖线性布局、层叠布局、弹性布局和网格布局,详细说明了各布局的特性及使用方法,例如线性布局中的排列、拉伸与缩放,弹性布局的方向、换行与对齐方式等。响应式布局则重点讲解了栅格系统和媒体查询,阐述如何通过栅格组件和媒体查询条件实现不同设备上的适配效果。这些技术帮助开发者灵活应对多尺寸屏幕的设计需求,提升用户体验。
138 55
|
2月前
|
存储 开发框架 API
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发二
本文详细介绍了基于声明式UI开发的健康饮食应用的设计与实现过程。内容涵盖从基础环境搭建到复杂功能实现的全流程,包括创建简单视图、构建布局(如Stack、Flex)、数据模型设计、列表与网格布局构建,以及页面跳转和数据传递等核心功能。 本文通过实际案例深入浅出地解析了声明式UI开发的关键技术和最佳实践,为开发者提供了宝贵的参考。
74 14
|
1月前
|
JavaScript 前端开发 开发者
09.HarmonyOS Next数据驱动UI开发:ForEach与动态渲染完全指南(上)
在现代前端开发中,数据驱动UI已成为主流开发范式。HarmonyOS Next的ArkTS语言和声明式UI框架完美支持这一理念,使开发者能够以更高效、更直观的方式构建复杂应用。
61 1
|
3月前
|
人工智能 物联网 编译器
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
108 11
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
327 0
|
11月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
130 0
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
225 0