[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, 大 ...
 
随机推荐
- Java 反射调用方法 - 不跳过安全检查、跳过安全检查和普通方法性能比较测试
			
java中反射提供灵活性同时,给运行效率带来了一定影响.写个代码测试一下 package com.xzlf.reflectTest; import java.lang.reflect.Method; ...
 - automake  autoconf 使用详解
			
本文地址: http://www.laruence.com/2009/11/18/1154.html 文章转自: http://www.linuxcomputer.cn/ 作为Linux下的程序开发人 ...
 - Debugging Under Unix: gdb Tutorial (https://www.cs.cmu.edu/~gilpin/tutorial/)
			
//注释掉 #include <iostream.h> //替换为 #include <iostream> using namespace std; Contents Intr ...
 - jdk 的 安装以及环境变量配置
			
第一步:下载jdk 下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html 第二步:安装jdk 第三步:配置环 ...
 - tomcat启动日志中中文乱码
			
场景 使用catalina.bat start命令启动tomcat7 方案 打开%catalina_home%/conf/logging.properties文件. 将其中的UTF-8代换为GBK. ...
 - 【ElasticSearch学习】之一图读懂文档索引全过程
			
ES索引过程详解: 1.客户端发送索引请求. 客户端向ES节点发送索引请求,以RestClient客户端发起请求为例: ES提供了Java High Level REST Client,用户可以通过R ...
 - 一只简单的网络爬虫(基于linux C/C++)————Url处理以及使用libevent进行DNS解析
			
Url处理 爬虫里使用了两个数据结构来管理Url 下面的这个数据结构用来维护原始的Url,同时有一个原始Url的队列 //维护url原始字符串 typedef struct Surl { char * ...
 - Java面试题:String、StringBuilder、StringBuffer区别
			
String:不可变字符序列. StringBuilder:可变字符序列.效率高.线程不安全,适合单线程. StringBuffer:可变字符序列.效率低.线程安全,适合多线程. 效率从高到低:Str ...
 - FastDFS文件服务器安装指南附安装包和自启动(看此篇就够了)
			
安装包在最后,本文为博主自己亲自安装记录 转载请注明出处 注意文字不清晰请放大看,放大看!! 安装包地址
 - C# 基础知识系列- 16 开发工具篇
			
0. 前言 这是C# 基础知识系列的最后一个内容讲解篇,下一篇是基础知识-实战篇.这一篇主要讲解一下C#程序的结构和主要编程工具. 1. 工具 工欲善其事必先利其器,在实际动手之前我们先来看看想要编写 ...