C# .net framework .net core 3.1 请求参数校验, DataAnnotations, 自定义参数校验
前言
在实际应用场景中我们常常要对接口的入参进行校验, 例如分页大小是否正确, 必填参数是否已经填写等等.
最简单的实现方式如下图, 这种在实际开发中代码过于冗余, 而且不灵活. 今天介绍一种统一参数校验的方式: System.ComponentModel.Annotations
教程
一. 使用nuget安装 System.ComponentModel.Annotations
二. 在请求参数上加属性
头部引用
using System.ComponentModel.DataAnnotations;
原生的组件上就提供了丰富的参数校验规则, 也支持自定义规则.
- Required 必填, 示例:[Required(ErrorMessage = "ID是必填项")] 需要注意除了string类型的其他的值类型由于会赋予默认值, 所以加这个属性的时候值类型字段需要设置为可为空 例如 int? Id {get;set;}
- Range 范围校验, 示例 [Range(1,99999999,ErrorMessage ="请输入正确的页码")]
- Compare 比较 与指定的字段值进行比较 [Compare("MyOtherProperty")]两个属性必须相同值,比如我们要求用户重复输入两次邮件地址时有用
- CreditCard 信用卡号
- EmailAddress 是否为邮件
- EnumDataType 校验枚举类型 示例: [EnumDataType(typeof(EnumModels.ResponseHttpCode),ErrorMessage = "未知的类型")]
- MaxLength 最大长度, 示例: [MaxLength(50,ErrorMessage = "昵称不能超过50个字")]
- MinLength 最小长度 , 示例: [MinLength(2,ErrorMessage = "昵称不能少于2个字")]
- StringLength 字符串长度不能超过给定的最大长度,也可以指定最小长度. 示例: [StringLength(50, ErrorMessage = "昵称只能介于2-50个字", MinimumLength = 2)]
- Url url格式, 示例: [Url(ErrorMessage = "链接格式错误")]
- RegularExpression 正则表达式 示例: [RegularExpression(@"^[1]{1}[3,4,5,6,7,8,9]{1}\d{9}$", ErrorMessage = "手机号码格式错误")]
三. 接口使用
请求参数
public class IdHeader
{
/// <summary>
/// Id
/// </summary>
[Required(ErrorMessage = "请填写id")]
public string Id { get; set; }
}
接口
public IActionResult TestCode([FromBody]IdHeader req)
{
return Ok(new
{
req.Id
});
}
在.net core 3.1中 我们请求时给id不负值, 将返回以下结果
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|ae306434-48bb5a7d72259168.",
"errors": {
"Id": [
"请填写id"
]
}
}
一般情况我们需要返回自己定义的格式, 所以我们需要先关闭自动校验, .net core 2.x和 .net framework默认是不自动校验的, 无需关闭
在Startup.cs里的ConfigureServices 添加如下代码关闭自动校验
//关闭参数自动校验,我们需要返回自定义的格式
services.Configure<ApiBehaviorOptions>((o) =>
{
o.SuppressModelStateInvalidFilter = true;
});
然后我们需要添加 OnActionExecuting 过滤器
添加过滤器
public class ActionFilter : IActionFilter
{
/// <summary>
/// action执行前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
//校验参数
if (!context.ModelState.IsValid)
{
var errorMsg = context.ModelState.Values.SelectMany(e => e.Errors).Select(e => e.ErrorMessage).FirstOrDefault();
context.Result = new OkObjectResult(new
{
Code = 702,
Msg = string.IsNullOrWhiteSpace(errorMsg) ? "参数校验错误" : errorMsg,
Data = new {}
});
return;
}
} /// <summary>
/// action执行后
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
.net core 使用过滤器, 在Startup.cs里的ConfigureServices 添加如下代码使用过滤器
services.AddMvc(o =>
{
//action 过滤器
o.Filters.Add<ActionFilter>();
})
.net webapi 使用过滤器, 在 webapiConfig.cs 里的 Register 里添加代码
config.Filters.Add(new App_Start.ActionFilter());//action过滤器
最后的结果
{
"code": 702,
"msg": "请填写id",
"data": {}
}
这样我们就可以自定义我们返回参数
四. 自定义参数校验
虽然官方已经提供了不少验证方法, 但是可能还不够我们使用, 例如身份证号, 行政区划代码等等.
电话号码官方已经提供了一个,但是不适用于我们中国, 我们以校验中国手机号码为例, 来讲自定义参数校验
主要方法是: 自定义类 , 继承 ValidationAttribute, 然后复写 IsValid
/// <summary>
/// 是否为中国手机号码
/// </summary>
public class ChinaMobilPhoneAttribute : ValidationAttribute
{
/// <summary>
/// 复写
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object value)
{
if (!(value is string)) return false; var val = (string)value;
return Regex.IsMatch(val, @"^[1]{1}[3,4,5,6,7,8,9]{1}\d{9}$");
}
}
然后入参校验
/// <summary>
/// Id 具体值请参考具体接口
/// </summary>
[ChinaMobilPhone(ErrorMessage = "请填写正确的手机号")]
public string PhoneNumber { get; set; }
测试
错误结果
正确结果
通过以上方式我们轻松实现各种参数校验
C# .net framework .net core 3.1 请求参数校验, DataAnnotations, 自定义参数校验的更多相关文章
- 简述C#中IO的应用 RabbitMQ安装笔记 一次线上问题引发的对于C#中相等判断的思考 ef和mysql使用(一) ASP.NET/MVC/Core的HTTP请求流程
简述C#中IO的应用 在.NET Framework 中. System.IO 命名空间主要包含基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库.和其他命名空间一样. System.I ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
- ASP.NET Core 开发 - Entity Framework (EF) Core
EF Core 1.0 Database First http://www.cnblogs.com/linezero/p/EFCoreDBFirst.html ASP.NET Core 开发 - En ...
- .Net Core 项目区域请求设置
.net core 和asp.net MVC区域请求有个区别,这里重点记录一下 asp.net MVC 区域请求直接是/区域名称/控制名称/方法名称,其他不需要设置任何东西,而Core 项目这样请求路 ...
- Core篇——初探Core的Http请求管道&&Middleware
目录: 1.Core 处理HTTP请求流程 2.中间件(Middleware)&&处理流程 3.创建自定义中间件&&模拟Core的请求管道 Core 处理HTTP请求流 ...
- C# .NET .NET Framework .NET CORE 等的关系简介
2019新的一年,祝大家新年快乐,工作生活一帆风顺,心想事成!诸事大吉! 这篇文章是我今年的第一篇博客,主题是:C# .NET .NET Framework .NET CORE 等这些名词之 ...
- Net Framework,Net Core 和 Net Standard 区别
前几天我在一个群里看到有关这方面的讨论,最后感觉讨论的不是很清晰,有幸的是我们的项目去年就开始迁移NetCore的调研了,我个人多多少少也是有过这方面的研究.下面我将说一下我自己对着三个的认识如果有不 ...
- 一张图搞定 .NET Framework, .NET Core 和 .NET Standard 的区别
最近开始研究.NET Core,有张图一看就能明白他们之前的关系. 上图己经能够说明.NET Framework和.NET Core其实是实现了 .NET Standard相关的东西,或者说Frame ...
- .net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml)
.net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml) 首先设置 Startup.cs 文件 配置 ConfigureServices services .Add ...
随机推荐
- zabbix 自动发现主机并关联模板
一.自动发现添加主机 1.利用agent自动发现主机 Configuration - Discovery -Create discovery rule 2.将自动发现的主机关联模板 Configura ...
- SpringBoot_自动装配
SpringBoot SrpingBoot 给人的第一印象就是 简洁,易上手.它是自 Spring 而来为了简化我们开发的,而经历过了 Spring 中繁琐的配置文件,我确实很好奇它到底是怎么帮我们把 ...
- Hyperledger Fabric Node SDK和应用开发
Hyperledger Fabric 提供了多种语言的SDK版本,其中提出比较早.比较稳定而全面的是Node.js版本的SDK. 前面提到的fabric示例(如first-network和e2e-cl ...
- HDU 6047 贪心思维题
Maximum Sequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 【git】git 常用命令(含删除文件)
Git常用操作命令收集: 1) 远程仓库相关命令 检出仓库:$ git clone git://github.com/jquery/jquery.git 查看远程仓库:$ git remote -v ...
- 实用算法系列之RT-Thread链表堆管理器
[导读] 前文描述了栈的基本概念,本文来聊聊堆是怎么会事儿.RT-Thread 在社区广受欢迎,阅读了其内核代码,实现了堆的管理,代码设计很清晰,可读性很好.故一方面了解RT-Thread内核实现,一 ...
- npm audit fix 报错
found 2504 vulnerabilities (1360 low, 1109 moderate, 29 high, 6 critical) run `npm audit fix` to fi ...
- kubeadm 搭建kubernetes集群环境
需求 kubeadm 搭建kubernetes集群环境 准备条件 三台VPS(本文使用阿里云香港 - centos7.7) 一台能SSH连接到VPS的本地电脑 (推荐连接工具xshell) 安装步骤 ...
- Unity实现写入json文件
using System.Collections; using System.Collections.Generic; using UnityEngine; using LitJson; using ...
- Java——枚举类(疯狂Java讲义6.9)
枚举类:有限而固定的类,使用enum关键字定义. 一个Java源文件中最多只能定义一个public访问权限的枚举类. 1.可实现一个或多个接口,默认集成了java.lang.Enum类(实现java. ...