快速掌握 ASP.NET 身份认证框架 Identity - 用户注册

推荐关注「码侠江湖」星标,时刻不忘江湖事

这是 ASP.NET Core Identity 系列的第二篇文章,上一篇文章介绍了 Identity 框架的集成,以及一些基础知识。

这篇文章讲一讲如何在 ASP.NET Core Identity 中实现用户注册。

点击上方或后方蓝字,阅读 ASP.NET Core Identity 系列合集。

本篇文章的示例项目:https://github.com/zilor-net/IdentitySample/tree/main/Sample02

46acd8c7757979144a8f344273565dee.png

准备工作

ASP.NET Core Identity 提供了很多不同的身份选项,帮助我们实现用户注册。

首先,让我们在 「Models」 文件夹中,创建一个用户注册模型:

public class UserRegistrationModel
{[Display(Name = "姓氏")]public string FirstName { get; set; }[Display(Name = "名字")]public string LastName { get; set; }[Display(Name = "电子邮箱")][Required(ErrorMessage = "电子邮箱不能为空")][EmailAddress]public string Email { get; set; }[Display(Name = "密码")][Required(ErrorMessage = "密码不能为空")][DataType(DataType.Password)]public string Password { get; set; }[Display(Name = "确认密码")][DataType(DataType.Password)][Compare("Password", ErrorMessage = "密码与确认密码不匹配。")]public string ConfirmPassword { get; set; }
}

这个类中的属性,需要用户在注册表单中填写。

其中,EmailPassword 属性是必需的,ConfirmPassword 属性的值必须与 Password 属性的值匹配。

有了这个模型,我们再来创建一个 「Account」 控制器:

public class AccountController : Controller
{[HttpGet]public IActionResult Register(){return View();}[HttpPost][ValidateAntiForgeryToken]public IActionResult Register(UserRegistrationModel userModel){return View();}
}

它有两个 Register 操作方法,用来提供用户注册功能。

第一个 Register 方法接受 Get 请求,用来显示注册表单的视图;

第二个 Register 方法接受 Post 请求,用来处理用户注册逻辑,并显示注册结果的视图。

还需要为 GET Register 操作,创建一个视图,这里我们可以直接使用 Create 模板,模型类选择 UserRegistrationModel 类即可。

5a8f805151b658c18bcc9cf63938bb4c.png

现在这个视图中的表单,已经可以为用户注册模型,提供所有的输入字段了。

需要注意的是,我们最好修改表单中 asp-validation-summary 的值为 All

因为,默认情况下,它只能显示模型验证产生的错误信息,而不会显示我们自己设置的验证错误。

视图中的 Create 按钮,会跳转到 POST 请求的 Register 操作方法,并且填充用户注册模型。

在 Web API 中使用来自用户的数据,最好采用数据传输对象的方式,但是在 MVC 中不一定如此。

这是因为 MVC 有模型的存在,在有视图的情况下,模型在一定程度上,替代了数据传输对象职责。

由于我们的数据通过视图传递,因此该类模型也被称为视图模型。

「UserRegistrationModel」 就是一个视图模型,如果我们想要真正的在数据库中存储它,必须要把它映射到 User 实体类。

我们需要安装 AutoMapper :

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

然后,在 Program 类中注册它:

builder.Services.AddAutoMapper(Assembly.GetExecutingAssembly());

接着,在布局页的导航菜单上,添加一个注册按钮。

因为后面还要添加登录按钮,所以为了代码的可维护性,我们可以创建一个分部视图:

// Shared\_LoginPartial.cshtml<ul class="navbar-nav"><li class="nav-item"><a class="nav-link text-dark" asp-controller="Account" asp-action="Register">注册</a>    </li>
</ul>

最后,修改 「_Layout.cshtml」 布局视图,在导航菜单上添加登录分布视图:

<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse"><partial name="_LoginPartial" /><!-- 添加 --><ul class="navbar-nav flex-grow-1">

注册操作

准备工作都已经完成了。

现在,让我们从用户注册逻辑开始。

首先,必须在 「Account」 控制器中,注入 AutoMapperUserManager 类:

private readonly IMapper _mapper;
private readonly UserManager<User> _userManager;
public AccountController(IMapper mapper, UserManager<User> userManager)
{_mapper = mapper;_userManager = userManager;
}

「UserManager」 由 Identity 框架提供,它负责帮助我们管理应用程序中的用户。

用户注册逻辑在 Post 请求的 Register 方法中实现:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(UserRegistrationModel userModel)
{if(!ModelState.IsValid){return View(userModel);}var user = _mapper.Map<User>(userModel);var result = await _userManager.CreateAsync(user, userModel.Password);if(!result.Succeeded){foreach (var error in result.Errors){ModelState.TryAddModelError(error.Code, error.Description);}return View(userModel);}await _userManager.AddToRoleAsync(user, "Guest");return RedirectToAction(nameof(HomeController.Index), "Home");
}

这里需要注意的是,我们把这个方法改成了异步的,因为 ·UserManager· 的助手方法也是异步的。

在方法内部,先检查模型的有效性,如果它是无效的,就返回带有无效模型的相同视图。

如果检查通过,就将 userModel 射到 user 实体。

使用 CreateAsync 方法用来注册用户,它会对密码进行哈希后保存。

之后,检查它返回的创建结果。

如果创建成功,我们只需在 UserManager 的帮助下,使用 AddToRoleAsync 方法,给用户添加一个默认的角色,并将用户重定向到 Index 页面。

但是如果注册失败,就遍历所有的错误,并将它们添加到 ModelState 中。

前面我们已经将视图的验证信息摘要改为了 All,否则这里添加的错误,不会显示出来。

最后,不要忘记创建 AutoMapper 的映射配置类:

// MappingProfile.cspublic class MappingProfile : Profile
{public MappingProfile(){CreateMap<UserRegistrationModel, User>().ForMember(user => user.UserName, expression => expression.MapFrom(userModel => userModel.Email));}
}

这里我们把电子邮件映射到用户名,因为我们在注册表单中没有提供用户名的字段。

现在启动应用,测试一下用户注册。

我可以尝试各种错误的注册内容,观察验证结果。

需要注意的是,默认的密码验证规则,非常的复杂,它不但要求有大小写字母,还必须要求你有一个特殊符号。

这个密码规则很不错,但是有时候我可能并不需要强规则。

而且我们使用了电子邮件作为用户名,但是默认情况下,没有要求电子邮件是唯一的。

所以,我们可以改变这些规则,这需要在注册 Identity 的地方,通过配置选项修改:

services.AddIdentity<User, IdentityRole>(options =>{options.Password.RequiredLength = 6;options.Password.RequireDigit = false;options.Password.RequireUppercase = false;options.Password.RequireNonAlphanumeric = false;options.Password.RequireLowercase = false;options.User.RequireUniqueEmail = true;})
.AddEntityFrameworkStores<ApplicationContext>();

比如,我们这里取消了数字、大写字母和特殊字符的验证,最小长度改为 6 位,同时设置电子邮件的唯一验证。

现在我们再来启动应用,测试一下注册过程,比如错误的密码格式、重复的电子邮箱。

大家通过一些测试可以发现,有些错误信息是中文的、有些则是英文的。

因为这个错误分为两种类型,一种是我们自定义的模型验证错误,我们已经设置了错误的信息,所以这种类型是中文的。

另一种是 ASP.NET Core Identity 内置的验证错误,它是我们通过在操作方法中,自己读取并添加进模型状态的。

因为 ASP.NET Core Identity 是英文版的,所以我们获取到的是英文信息,

不过,我们也可以自行定义中文信息,这需要我们创建一个自定义的错误描述类:

public class CustomIdentityErrorDescriber : IdentityErrorDescriber
{public override IdentityError PasswordTooShort(int length){return new(){Code = nameof(PasswordTooShort),Description = $"密码至少需要 {length} 位"};}public override IdentityError DuplicateEmail(string email){return new(){Code = nameof(DuplicateUserName), Description = $"电子邮箱 {email} 已存在。"};}public override IdentityError DuplicateUserName(string username){return new(){Code = nameof(DuplicateUserName), Description = $"用户名 {username} 已存在。"};}

自定义的错误信息,需要通过覆写 「IdentityErrorDescriber」 基类的错误方法,设置你想要的错误描述。

需要的话,你可以通过阅读源码,找到所有的错误方法。

我们还需要把它配置到注册 Identity 服务的方法中:

AddErrorDescriber<CustomIdentityErrorDescriber>()

小结

现在,我们已经实现了用户注册,具体的代码可以参看示例项目,下篇文章将会继续讲解用户登陆以及身份认证。

更多精彩内容,请关注我▼▼

5bc5756b77a8671cb9d5d29913cf1172.gif

如果喜欢我的文章,那么

在看和转发是对我最大的支持!

(戳下面蓝字阅读)

d07925ccd5e268e0814287d660691a6c.png

推荐关注微信公众号:码侠江湖

                        8b2e3e41862831cde44bda4b32836e69.png觉得不错,点个在看再走哟

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

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

相关文章

【GIS风暴】30米分辨率地表覆盖数据GlobeLand30原始数据集简介及下载地址

数据集预览&#xff1a; GlobeLand30是30米空间分辨率全球地表覆盖数据&#xff0c;目前可供下载使用的有3年的数据&#xff1a;2000-2010-2020&#xff0c;本文主要讲述GlobeLand30的官网下载地址和数据集简介。 数据处理方法、成果数据下载&#xff1a; 【ArcGIS风暴】ArcGI…

一、基础折线图详解《手把手教你 ECharts 数据可视化详解》

注&#xff1a;本系列教程需要对应 JavaScript 、html、css 基础&#xff0c;否则将会导致阅读时困难&#xff0c;本教程将会从 ECharts 的官方示例出发&#xff0c;详解每一个示例实现&#xff0c;从中学习 ECharts 。 ECharts 官方示例&#xff1a;https://echarts.apache.o…

NLog自定义Target之MQTT

NLog是.Net中最流行的日志记录开源项目(之一)&#xff0c;它灵活、免费、开源官方支持文件、网络(TCP、UDP)、数据库、控制台等输出社区支持Elastic、Seq等日志平台输出实时日志需求在工业物联网等特定场景下需要实时获取日志信息工业物联网领域常用的是mqtt协议那我们就使用NL…

2016-1-27

2019独角兽企业重金招聘Python工程师标准>>> 1.前端的三大技能:1.1.描述网页内容html 1.2.描述网页样式css 1.3.描述网页行为js2.html和jsp区别在于静态和动态..bootsharp是目前比较火爆的css..angular是目前比较火爆的js.3.单点登陆(SSO):登陆一次就可以访问所有相…

【ArcGIS风暴】ArcGIS生成GlobeLand30土地利用数据集中国区域行列号shp格式对照图(附shp下载)

效果预览: 本文主要讲述了在ArcGIS中生成GlobeLand中国区域对照行列号的shp格式矢量数据,用途在于将自己的研究区跟行列号矢量图层直接叠加显示,快速找出自己所需要的图幅号,便于快速下载数据。同时为了方便使用,本文提供了对照图的下载。 文章目录 1. 创建文件数据库2. 创…

Android 节操视频播放器jiecaovideoplayer自定义播放音频使用:屏蔽全屏按钮,增加倒计时,当前时间/总时间

一、屏蔽全屏按钮 找到JCVideoPlayerStandard.java文件中的代码&#xff1a; private void fixAudio() {if (SrcType.equalsIgnoreCase("Audio")) {//如果是音频&#xff0c;始终显示coverImageView//thumbImageView.setVisibility(View.VISIBLE);coverImageView.se…

一、Qt初尝试,做一个QT计算器《QT 入门到实战》

学习目标 了解 qt 的基本信息了解 qt 的下载及安装了解创建一个基本 qt 项目的流程了解信号与槽通过示例了解信号与槽的设置与编写了解控件添加的方式了解控件如何使用代码获取其文本了解控件如何使用代码设置其文本使用 connect 自定义信号与槽了解使用样式修饰控件外观了解使…

VS C#语言获取输入名称的汉语拼音简拼码和全拼码完整案例教程

结果预览: 扩展阅读: SQL语言获取拼音码:SQL Server编写函数获取汉字的拼音码(简拼) 文章目录 1. 拼音码类编写2. 界面设计3. 前端调用4. 结果展示1. 拼音码类编写 打开Visual Studio,新建一个Winform项目,再添加一个类文件,命名为PYM。 键入如下代码: using Syst…

SSIS 执行变量中的脚步输出列顺序与SQL查询列顺序不同

这个问题是朋友遇到的&#xff0c;做一个SSIS的程序将数据导入到txt。然后再用Oracle的工具导入到Oracle。但是在SSIS中执行变量脚步的时候&#xff0c;发现输出的列名称跟查询的列名称完全不同。比如Schema_id在查询的第三列&#xff0c;但是输出的时候到了第6列。 如图&#…

【ArcGIS风暴】ArcGIS自定义坐标系统案例教程---以阿尔伯斯投影(Albers)为例

在实际工作中,经常需要进行矢量数据或栅格数据的投影转换工作,但有时候ArcGIS中恰恰没有我们需要的坐标系,此时,就需要我们自定义坐标系。本文以阿尔伯斯投影(Albers)为例,讲解自定义投影的一般过程及注意事项。 文章目录 1. 确定投影名称2. 选择投影坐标系及修改参数4.…

Unity5 GI与PBS渲染从用法到着色代码

本文主要介绍Untiy5以后的GI&#xff0c;PBS&#xff0c;以及光源探头&#xff0c;反射探头的用法以及在着色器代码中如何发挥作用&#xff0c;GI是如何影响渲染的&#xff0c;主要分成三个部分&#xff0c;最开始说明PBS需要的材质与相应概念&#xff0c;二是Unity 里相应GI的…

Blazor University (31)表单 —— 验证

原文链接&#xff1a;https://blazor-university.com/forms/validation/验证源代码[1]DataAnnotationsValidator 是 Blazor 中的标准验证器类型。在 EditForm 组件中添加此组件将启用基于 System.ComponentModel.DataAnnotations.ValidationAttribute 的 .NET 属性的表单验证。…

CSDN,CNBLOGS博客文章一键转载插件 终于更新了!

之前&#xff0c;Shawn Chou等朋友一直建议插件支持cnblogs文章转载&#xff0c;但一直没时间修改插件&#xff0c;今天晚上抽时间将插件进行了升级&#xff0c;可以支持 CSDN,CNBLOGS博客文章的一键转载。时间仓促&#xff0c;难免有各种问题&#xff0c;欢迎提出建议&#xf…

ROS2_Control官方资料+运动控制

Getting Started — ROS2_Control: Rolling Dec 2023 documentation Getting Started Edit on GitHub Youre reading the documentation for a development version. For the latest released version, please have a look at Iron. Getting Started Installation Binar…

三、教你搞懂渐变堆叠面积图《手把手教你 ECharts 数据可视化详解》

注&#xff1a;本系列教程需要对应 JavaScript 、html、css 基础&#xff0c;否则将会导致阅读时困难&#xff0c;本教程将会从 ECharts 的官方示例出发&#xff0c;详解每一个示例实现&#xff0c;从中学习 ECharts 。 ECharts 官方示例&#xff1a;https://echarts.apache.o…

试用了多款报表工具,终于找到了基于.Net 6开发的一个了

Part1前言上一个月有一个项目需要用到数据分析&#xff0c;将老板感兴趣的数据给他整理成一个面板&#xff0c;方便他实时查看&#xff0c;于是自己了解到了BI,当时我们项目就用了metabase&#xff0c;metabase是一款开源的BI分析工具&#xff0c;开发语言clojureReact为主。就…

4种CSS文字竖排方法

2019独角兽企业重金招聘Python工程师标准>>> 有时候&#xff0c;我们需要对网页某个区域的文字竖排&#xff0c;竖向排列&#xff0c;横向的当然大家都见惯了&#xff0c;对于竖排&#xff0c;一时间找不到思路了&#xff0c;呵呵&#xff0c;其实和横排一样简单&am…

【ArcGIS风暴】ArcGIS10.6创建LAS数据集的两种方法并加载点云数据

文章目录 1. 使用上下文菜单创建 LAS 数据集2. 使用地理处理工具创建 LAS 数据集3. 显示LAS数据集LAS 数据集是位于文件夹中的独立文件,并且引用 LAS 格式的激光雷达数据和用于定义表面特征的可选表面约束要素。可使用创建 LAS 数据集工具或 ArcCatalog 中文件夹的上下文菜单快…

关于建立北京市专业技术人员职业资格与职称对应关系的通知

原文地址 http://www.bjrbj.gov.cn/xxgk/gsgg/201906/t20190605_82857.html 附件 北京市专业技术人员职业资格与职称对应表 &#xff08;46项&#xff09; 一、准入类职业资格 序号 资格名称 可聘专业技术职务 1 注册消防工程师 一级注册消防工程师&#xff1a;工程师 二…

【Pix4d精品教程】Pix4d项目空三结果精度评估完整解决方案

《无人机航空摄影测量精品教程》合集目录(Pix4d、CC、EPS、PhotoScan、Inpho) 文章目录 一、单体项目评估二、整体项目评估在航测项目内业工作中,不管是垂直摄影,还是倾斜摄影,最核心的部分是空三加密,一个很重要的基础是共线方程。空三结果的精度是航测的基本要求,也会…