前言

在实际应用场景中我们常常要对接口的入参进行校验, 例如分页大小是否正确, 必填参数是否已经填写等等.

最简单的实现方式如下图, 这种在实际开发中代码过于冗余, 而且不灵活. 今天介绍一种统一参数校验的方式: 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, 自定义参数校验的更多相关文章

  1. 简述C#中IO的应用 RabbitMQ安装笔记 一次线上问题引发的对于C#中相等判断的思考 ef和mysql使用(一) ASP.NET/MVC/Core的HTTP请求流程

    简述C#中IO的应用   在.NET Framework 中. System.IO 命名空间主要包含基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库.和其他命名空间一样. System.I ...

  2. 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 ...

  3. 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 ...

  4. .Net Core 项目区域请求设置

    .net core 和asp.net MVC区域请求有个区别,这里重点记录一下 asp.net MVC 区域请求直接是/区域名称/控制名称/方法名称,其他不需要设置任何东西,而Core 项目这样请求路 ...

  5. Core篇——初探Core的Http请求管道&&Middleware

    目录: 1.Core 处理HTTP请求流程 2.中间件(Middleware)&&处理流程 3.创建自定义中间件&&模拟Core的请求管道 Core 处理HTTP请求流 ...

  6. C# .NET .NET Framework .NET CORE 等的关系简介

    2019新的一年,祝大家新年快乐,工作生活一帆风顺,心想事成!诸事大吉! 这篇文章是我今年的第一篇博客,主题是:C#  .NET  .NET Framework   .NET CORE  等这些名词之 ...

  7. Net Framework,Net Core 和 Net Standard 区别

    前几天我在一个群里看到有关这方面的讨论,最后感觉讨论的不是很清晰,有幸的是我们的项目去年就开始迁移NetCore的调研了,我个人多多少少也是有过这方面的研究.下面我将说一下我自己对着三个的认识如果有不 ...

  8. 一张图搞定 .NET Framework, .NET Core 和 .NET Standard 的区别

    最近开始研究.NET Core,有张图一看就能明白他们之前的关系. 上图己经能够说明.NET Framework和.NET Core其实是实现了 .NET Standard相关的东西,或者说Frame ...

  9. .net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml)

    .net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml) 首先设置 Startup.cs 文件 配置 ConfigureServices services .Add ...

随机推荐

  1. Go语言学习目录

    第一章 Go环境搭建 1.1 Linux搭建Go环境 1.2 Mac搭建Go环境 1.3 Windows搭建Go环境 第二章 Go语言特性 2.1 Go特征 2.2 Go变量类型 2.3 Go内置函数 ...

  2. C# winform DataGridView 绑定数据的的几种方法

    1.用DataSet和DataTable为DataGridView提供数据源 String strConn = "Data Source=.;Initial Catalog=His;User ...

  3. CF834D

    题目链接:http://codeforces.com/contest/834/problem/D 题目大意:将一个有n个数的数列分成k段,每段的价值为该段中不同数字的个数,求k段的最大总价值. 解题思 ...

  4. .Net基础之2——C#基础

    1.注释符的作用   1).注销                  2).解释 2.C#中的3种解释符 1).单行注释(//要注释的内容) //这行代码的作用是将hello world输出到控制台上 ...

  5. layui 让弹窗始终居中于屏幕

    前话:今天用 layer.confirm()  弹窗的时候,滚动到页面尾部再弹窗时,发现弹窗还显示在上面,要滚动会上面才能看到. 度娘找了一个获取滚动条位置的方法: function ScollPos ...

  6. python 生成随机字符串

    1.生成随机字符串 #数字+字母+符号 def getRandChar(n): l = [] #sample = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^ ...

  7. GitHub 热点速览 Vol.21:Go 新手起手式,学就完事儿了

    作者:HelloGitHub-小鱼干 摘要:说到学习之道,方法很重要,好的学习方法能让你比他人更快地入门到精通,比如本周被 3k 多人 pick 的 learngo 项目,它收录了多个例子和练习,新手 ...

  8. WEB常见攻击及防御

    对于一个Web应用来说,可能会面临很多不同的攻击.下面的内容将介绍一些常见的攻击方法,以及面对这些攻击的防御手段. 一.跨站脚本攻击(XSS) 跨站脚本攻击的英文全称是Cross Site Scrip ...

  9. android小Demo--圆球跟随手指轨迹移动

    eatwhatApp的客户端基本实现,会再后续进行整改,今天做一个在网上找到的小Demo,让屏幕中出现一个圆球,并跟随手指移动. 写个java类DrawView继承于View: public clas ...

  10. Java IO(十一) DataInputStream 和 DataOutputStream

    Java IO(十一) DataInputStream 和 DataOutputStream 一.介绍 DataInputStream 和 DataOutputStream 是数据字节流,分别继承自 ...