简要说明

【项目源码】

【章节目录】

本文主要介绍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的使用的更多相关文章

  1. [Abp vNext 入坑分享] - 前言

    一·背景 Abp vnext是 ABP 框架作者所发起一个完全基于 ASP .NET Core框架,截至2020年4月份已经升级到2.5.0版本,根据经验2.0版本以后可以放心的使用在生产环境.类似a ...

  2. [Abp vNext 入坑分享] - 8.Redis与Refit的接入

    前言 本章结束之后,这个abp vnext系列算是初步完结了,基础的组件都已经接入了.如果各位还需要其它的组件的话,可以自己按需要进行接入使用.其实这个只是一个基础的框架,可以自己根据需要进行变通的. ...

  3. [Abp vNext 入坑分享] - 3.简单的用户模块功能开发

    一.简要说明 本篇文章开始进行业务模块的开发模拟,借助user模块来进行业务开发,主要是用户相关的基础操作.主要是先使用Users来体验整个开发的流程.主要是先把一个基础流程跑顺利,在这里我并不会过于 ...

  4. [Abp vNext 入坑分享] - 4.JWT授权的接入

    一.感想 在写这一系列文章之前,本来以为写这个之前已经搭建好的框架描述会比较简单,但是慢慢写下来才发现.写这个真的不简单额,本来以为图文一起,一个晚上应该能输出一篇吧...结果:现实真的骨感,一个星期 ...

  5. [Abp vNext 入坑分享] - 1.创建初始的项目

    一.简要说明 本篇文章主要是跟着官方的文档把项目安装好先,同时了解一下大概的项目结构. 二.具体步骤 2.1全局安装ABP CLI,直接在cmd中安装即可.如果你之前安装过,这里可以略过: dotne ...

  6. [Abp vNext 入坑分享] - 6.完整接入swagger

    前言 由于最近一直在修改一下排版,同时找了非技术的朋友帮忙看一下排版的问题,现在已经基本上确定了排版和样式了.更新可以恢复正常了. 作为一个写前端代码基本只写js不写css的开发,搞排版真的头疼..各 ...

  7. [Abp vNext 入坑分享] - 2.简化项目结构

    一.简要说明 本篇文章根据我自己的需要对项目结果进行简化,让项目结构更符合我自己的要求,同时让项目跑起来.仅供参考 二.具体步骤 2.1卸载掉对我来说目前使用不上的项目,identityserver, ...

  8. [Abp vNext 入坑分享] - 5.全局异常替换

    一.简要说明 [项目源码] [章节目录]   前面我们已经初步完成了框架的功能了,jwt的也已经接入完成了.   现在需要进行全局异常的接入了,abpvnext官方本来就有了全局异常的模块了,介绍链接 ...

  9. Abp vnext EFCore 实现动态上下文DbSet踩坑记

    背景 我们在用EFCore框架操作数据库的时候,我们会遇到在 xxDbContext 中要写大量的上下文 DbSet<>; 那我们表少还可以接受,表多的时候每张表都要写一个DbSet, 大 ...

随机推荐

  1. jQuery的attr和prop属性

    <div id="div1"></div> attr: 首先是一个参数的attr. $("#div").attr("id&qu ...

  2. 2019-2020-1 20199325《Linux内核原理与分析》第十二周作业

    什么是ShellShock? Shellshock,又称Bashdoor,是在Unix中广泛使用的Bash shell中的一个安全漏洞,首次于2014年9月24日公开.许多互联网守护进程,如网页服务器 ...

  3. 飞机大战-面向对象-pygame

    飞机大战 最近学习了python的面向对象,对面向对象的理解不是很深刻. 面向对象是数据和函数的'打包整理',将相关数据和处理数据的方法集中在一个地方,方便使用和管理. 本着学习的目的,在网上找了这个 ...

  4. Babel 在浏览器环境使用方法

    Babel 也可以用于浏览器环境.但是,从 Babel 6.0 开始,不再直接提供浏览器版本,而是要用构建工具构建出来.如果你没有或不想使用构建工具 1.通过安装5.x版本的babel-core模块获 ...

  5. 在 AutoLayout 和 Masonry 中使用动画

    动画是 iOS 中非常重要的一部分,它给用户展现出应用灵气的一面. 在动画块中修改 Frame 在原来使用 frame 布局时,在 UIView 的 animate block 中对 view 的布局 ...

  6. NetCore项目实战篇02---全局异常处理

    在 .netcore中可以自定义自己的异常类型,步骤如下: 1.自定义自己的异常类型UserOperationException 并继承自Exception public class UserOper ...

  7. 数学--数论--随机算法--Pollard Rho 大数分解算法(纯模板带输出)

    ACM常用模板合集 #include <bits/stdc++.h> using namespace std; typedef long long ll; ll pr; ll pmod(l ...

  8. predixy源码学习

    Predixy是一个代理,代理本质上就是用来转发请求的.其主要功能就是接收客户端的请求,然后把客户端请求转发给redis服务端,在redis服务端处理完消息请求后,接收它的响应,并把这个响应返回给客户 ...

  9. 【Layui__监听button】在form中监听按钮事件

    1. 前言 在使用form表单的按钮时,点击按钮总是页面刷新,代码如下 <button class="layui-btn" lay-submit lay-filter=&qu ...

  10. Java——字节和字符的区别

    字节 1.bit=1  二进制数据0或1 2.byte=8bit  1个字节等于8位 存储空间的基本计量单位 3.一个英文字母=1byte=8bit 1个英文字母是1个字节,也就是8位 4.一个汉字= ...