[Abp vNext 入坑分享] - 7.Automapper与validation的使用
简要说明
本文主要介绍Automapper与Validation的使用方法。首先使用Automapper的目的是引入组件完成entity与dto之间的转换以达到简化代码的目的。Abp vnext的项目中已经默认添加好此组件了【介绍】,本文只是说一些简单的用法,更进一步的使用需要到automapper的官网中查看文档
其次是Validation主要是用于入参校验,通过对dto标注相应的属性达到入参校验的功能。【abp介绍】【官方介绍】
具体步骤
1、Automapper的基础使用方法,在官方的文档中也有比较清晰的说明,所以就只是简单的根据官方文档写一次。然后试运行一下简单的效果即可。添加相应的mapper使用的Dto,如UserDto,定义好可以对外输出的属性。
public class UserDto: EntityDto<Guid>
{
/// <summary>
/// 用户名称
/// </summary>
public string user_name { get; set; }
/// <summary>
/// 用户手机号
/// </summary>
public string user_phone { get; set; }
/// <summary>
/// 用户状态
/// </summary>
public int user_status { get; set; }
}
其次在AbpVnext.Learn.Application中找到LearnApplicationAutoMapperProfile类,添加我们需要的mapper,CreateMap<User, UserDto>(); 最后在UserAppServices里面添加以下代码,其中ObjectMapper.Map就是转换的方法。
public async Task<UserDto> LoginByUserPhoneAndPwd(string user_phone,string pass_word)
{
var user= await _repository.FindAsync(a=>a.user_phone== user_phone&&a.pass_word== pass_word&&a.user_status==0);
return ObjectMapper.Map<User, UserDto>(user);
}
调试代码,输出结果如下,转换正常:

2、接下来主要介绍一下Validation的用法,官方的Validation是一个简单与轻量化的组件,主要用数据注解的方式对入参字段的合法性校验上。下面我们先来做一个简单的例子,原来登录接口的入参的参数增加以下[Required]
/// <summary>
/// 登录的Dto
/// </summary>
public class LoginDto:
{
/// <summary>
/// 用户手机号
/// </summary>
[Required]
public string user_phone { get; set; }
/// <summary>
/// 登录密码
/// </summary>
[Required]
public string pass_word { get; set; }
}
然后调试代码,测试相应接口,如下图抛出500异常,

再看日志,显示的是校验失败异常,则表明我们的注解生效了。

3、上面虽然显示我们的校验生效了,但是输出的结果明显不是我们想要的结果。一般我们需要为校验失败的入参输出统一的code和相应的字符串,让我们的提示比较清晰明了,同时也让前端开发的同事比较明确的知道这个是由于参数校验引起的问题,然后去修正相关参数。因此,我们需要替换掉abp的原有校验异常输出。
首先我们查看官方文档有说明,校验异常统一为AbpValidationException 。

因此我们在原来的LeanGlobalExceptionFilter中拦截此类型的异常,并将输出修改为code=100,如下:
public void OnException(ExceptionContext context)
{
logger.LogError(new EventId(context.Exception.HResult),
context.Exception,
context.Exception.Message);
if (context.Exception is AbpValidationException)
{
context.Result = new JsonResult(new { ode = 100, msg = context.Exception.Message });
}
else
{
context.Result = new JsonResult(new { code = 500, msg = "系统异常" });
}
context.ExceptionHandled = true;
}
然后我们再来看看调试接口的输出结果,如下,则表明我们的替换是成功了。

4、但是这样就算成功了吗?当然不是额,abp所有的校验失败输出都是输出这个:ModelState is not valid! See ValidationErrors for details.这样的输出,对我们前端或客户端同事是非常不友好的输出,都不知道错误原因与相应的字段,因此我们需要进一步去优化这些信息以达到最大程度的减少沟通成本的目的。下面我们来看看如何进行操作吧!
4.1、首先我们看一下注解里面的ValidationAttribute,这个注解包含了字段ErrorMessage是用于输出校验错误的字段的,所以我们可以好好的利用一下这个ErrorMessage来达到我们的目的。把user_phone的[Required]修改成[Required(ErrorMessage ="手机号码不能为空")]
4.2、我们回到LeanGlobalExceptionFilter这里,看一下AbpValidationException里面包含了什么信息。

如图所示,我们看到了ValidationErrors这个字段是一个List,里面包含了我们这一个请求入参的整个dto里所有校验不通过的信息列表。这样就好办了,修改原来的拦截为以下代码:
public void OnException(ExceptionContext context)
{
logger.LogError(new EventId(context.Exception.HResult),
context.Exception,
context.Exception.Message);
if (context.Exception is AbpValidationException)
{
var validateerros = ((AbpValidationException)context.Exception).ValidationErrors;
context.Result = new JsonResult(new { ode = 100, msg = validateerros.Count > 0 ? validateerros[0].ErrorMessage : context.Exception.Message });
}
else
{
context.Result = new JsonResult(new { code = 500, msg = "系统异常" });
}
context.ExceptionHandled = true;
}
然后调试代码,并测试相应的接口。现在则表示显示正常了。至于信息到底是显示第一个还是最后一个,自己判断,个人感觉都可以,因为都属于参数失败的校验

4.3、接下来我们使用一下进阶的判断,脱离于单纯的字段校验,如:假如user_phone等于pass_word的时候抛出不能相等提示。这个需要dto继承IValidatableObject然后增加Validate的实现方法,如下:
public IEnumerable<ValidationResult> Validate(
ValidationContext validationContext)
{
if (user_phone == pass_word)
{
yield return new ValidationResult(
"手机号码与密码不能一样!",
new[] { "user_phone", "pass_word" }
);
}
}
然后调试代码,并测试相应的接口,如下则表示替换成功了。。

[Abp vNext 入坑分享] - 7.Automapper与validation的使用的更多相关文章
- [Abp vNext 入坑分享] - 前言
一·背景 Abp vnext是 ABP 框架作者所发起一个完全基于 ASP .NET Core框架,截至2020年4月份已经升级到2.5.0版本,根据经验2.0版本以后可以放心的使用在生产环境.类似a ...
- [Abp vNext 入坑分享] - 8.Redis与Refit的接入
前言 本章结束之后,这个abp vnext系列算是初步完结了,基础的组件都已经接入了.如果各位还需要其它的组件的话,可以自己按需要进行接入使用.其实这个只是一个基础的框架,可以自己根据需要进行变通的. ...
- [Abp vNext 入坑分享] - 3.简单的用户模块功能开发
一.简要说明 本篇文章开始进行业务模块的开发模拟,借助user模块来进行业务开发,主要是用户相关的基础操作.主要是先使用Users来体验整个开发的流程.主要是先把一个基础流程跑顺利,在这里我并不会过于 ...
- [Abp vNext 入坑分享] - 4.JWT授权的接入
一.感想 在写这一系列文章之前,本来以为写这个之前已经搭建好的框架描述会比较简单,但是慢慢写下来才发现.写这个真的不简单额,本来以为图文一起,一个晚上应该能输出一篇吧...结果:现实真的骨感,一个星期 ...
- [Abp vNext 入坑分享] - 1.创建初始的项目
一.简要说明 本篇文章主要是跟着官方的文档把项目安装好先,同时了解一下大概的项目结构. 二.具体步骤 2.1全局安装ABP CLI,直接在cmd中安装即可.如果你之前安装过,这里可以略过: dotne ...
- [Abp vNext 入坑分享] - 6.完整接入swagger
前言 由于最近一直在修改一下排版,同时找了非技术的朋友帮忙看一下排版的问题,现在已经基本上确定了排版和样式了.更新可以恢复正常了. 作为一个写前端代码基本只写js不写css的开发,搞排版真的头疼..各 ...
- [Abp vNext 入坑分享] - 2.简化项目结构
一.简要说明 本篇文章根据我自己的需要对项目结果进行简化,让项目结构更符合我自己的要求,同时让项目跑起来.仅供参考 二.具体步骤 2.1卸载掉对我来说目前使用不上的项目,identityserver, ...
- [Abp vNext 入坑分享] - 5.全局异常替换
一.简要说明 [项目源码] [章节目录] 前面我们已经初步完成了框架的功能了,jwt的也已经接入完成了. 现在需要进行全局异常的接入了,abpvnext官方本来就有了全局异常的模块了,介绍链接 ...
- Abp vnext EFCore 实现动态上下文DbSet踩坑记
背景 我们在用EFCore框架操作数据库的时候,我们会遇到在 xxDbContext 中要写大量的上下文 DbSet<>; 那我们表少还可以接受,表多的时候每张表都要写一个DbSet, 大 ...
随机推荐
- python学习22之函数式编程
'''''''''1.高阶函数:将函数作为参数传递到另一个函数中,作为这个函数的参数,这样的方式叫高阶函数(1)map:两个参数,一个是函数,一个是iterator,将函数依次作用于Iterator中 ...
- SVN diff
http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.diff.html Name svn diff (di) — This displays the di ...
- Linux 文件常用权限
-rw------- (600) 只有所有者才有读和写的权限 -rw-r--r-- (644) 只有所有者才有读和写的权限,组群和其他人只有读的权限 -rwx------ (700) 只有所有者才有读 ...
- Redis介绍及字符串操作
一.前言 不同程序之间实现通信的方法? A.通过不同程序之间建立socket,实现通信.实际应用适用于使用broker,如RabbitMQ,ZeroMQ. B.通过Json,Pickle,利用文件的写 ...
- Eclipse新建类的时候如何自动添加注释(作者,时间,版本等信息)
为什么80%的码农都做不了架构师?>>> 方法一:Eclipse中设置在创建新类时自动生成注释 windows–>preference Java–>Code Sty ...
- Codeforces Round #618 (Div. 2)-B. Assigning to Classes
Reminder: the median of the array [a1,a2,-,a2k+1] of odd number of elements is defined as follows: l ...
- 基于UDP的客户端和服务器端的代码设计
实验平台 linux 实验内容 编写UDP服务器和客户端程序,客户端发送消息,服务器接收消息,并打印客户端的IP地址和端口号. 实验原理 UDP是无需连接的通信,其主要实现过程如下: 同样,我们可以按 ...
- pytho xlrd简介
xlrd:是什么? xlrd是python的一个模块,主要用来对Excel进行读的操作,相对应的,xlwd就是对Excel进行写的模块了. xlrd中有哪些方法可以用呢? 1.打开Excel文件读取数 ...
- XCTF练习题-WEB-webshell
XCTF练习题-WEB-webshell 解题步骤: 1.观察题目,打开场景 2.根据题目提示,这道题很有可能是获取webshell,再看描述,一句话,基本确认了,观察一下页面,一句话内容,密码为sh ...
- Python解决钻石小偷问题
题目如下: A:我没有偷钻石. B:D就是罪犯. C:B是盗窃这块钻石的罪犯. D:B有意诬陷我. 假定只有一个人说的是真话,编程序判断谁偷走了钻石. 答案是:说真话的是D,罪犯是A,逻辑思路可以百度 ...