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 ...
随机推荐
- Go语言学习目录
第一章 Go环境搭建 1.1 Linux搭建Go环境 1.2 Mac搭建Go环境 1.3 Windows搭建Go环境 第二章 Go语言特性 2.1 Go特征 2.2 Go变量类型 2.3 Go内置函数 ...
- C# winform DataGridView 绑定数据的的几种方法
1.用DataSet和DataTable为DataGridView提供数据源 String strConn = "Data Source=.;Initial Catalog=His;User ...
- CF834D
题目链接:http://codeforces.com/contest/834/problem/D 题目大意:将一个有n个数的数列分成k段,每段的价值为该段中不同数字的个数,求k段的最大总价值. 解题思 ...
- .Net基础之2——C#基础
1.注释符的作用 1).注销 2).解释 2.C#中的3种解释符 1).单行注释(//要注释的内容) //这行代码的作用是将hello world输出到控制台上 ...
- layui 让弹窗始终居中于屏幕
前话:今天用 layer.confirm() 弹窗的时候,滚动到页面尾部再弹窗时,发现弹窗还显示在上面,要滚动会上面才能看到. 度娘找了一个获取滚动条位置的方法: function ScollPos ...
- python 生成随机字符串
1.生成随机字符串 #数字+字母+符号 def getRandChar(n): l = [] #sample = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^ ...
- GitHub 热点速览 Vol.21:Go 新手起手式,学就完事儿了
作者:HelloGitHub-小鱼干 摘要:说到学习之道,方法很重要,好的学习方法能让你比他人更快地入门到精通,比如本周被 3k 多人 pick 的 learngo 项目,它收录了多个例子和练习,新手 ...
- WEB常见攻击及防御
对于一个Web应用来说,可能会面临很多不同的攻击.下面的内容将介绍一些常见的攻击方法,以及面对这些攻击的防御手段. 一.跨站脚本攻击(XSS) 跨站脚本攻击的英文全称是Cross Site Scrip ...
- android小Demo--圆球跟随手指轨迹移动
eatwhatApp的客户端基本实现,会再后续进行整改,今天做一个在网上找到的小Demo,让屏幕中出现一个圆球,并跟随手指移动. 写个java类DrawView继承于View: public clas ...
- Java IO(十一) DataInputStream 和 DataOutputStream
Java IO(十一) DataInputStream 和 DataOutputStream 一.介绍 DataInputStream 和 DataOutputStream 是数据字节流,分别继承自 ...