菜鸟入门【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>

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

相关文章
|
21天前
|
开发框架 NoSQL .NET
利用分布式锁在ASP.NET Core中实现防抖
【9月更文挑战第5天】在 ASP.NET Core 中,可通过分布式锁实现防抖功能,仅处理连续相同请求中的首个请求,其余请求返回 204 No Content,直至锁释放。具体步骤包括:安装分布式锁库如 `StackExchange.Redis`;创建分布式锁服务接口及其实现;构建防抖中间件;并在 `Startup.cs` 中注册相关服务和中间件。这一机制有效避免了短时间内重复操作的问题。
|
30天前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
1月前
|
前端开发 JavaScript C#
C#开发者的新天地:Blazor如何颠覆传统Web开发,打造下一代交互式UI?
【8月更文挑战第28天】Blazor 是 .NET 生态中的革命性框架,允许使用 C# 和 .NET 构建交互式 Web UI,替代传统 JavaScript。本文通过问答形式深入探讨 Blazor 的基本概念、优势及应用场景,并指导如何开始使用 Blazor。Blazor 支持代码共享、强类型检查和丰富的生态系统,简化 Web 开发流程。通过简单的命令即可创建 Blazor 应用,并利用其组件化和数据绑定特性快速搭建界面。无论对于 .NET 还是 Web 开发者,Blazor 都是一个值得尝试的新选择。
55 1
|
1月前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
33 0
|
1月前
|
开发框架 监控 .NET
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
|
1月前
|
Linux C# C++
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
|
1月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
33 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
155 0
|
4月前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
67 0
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
153 0