前言

在framework的mvc中,经常会使用 Model.StateModelState.IsValid 配合着特性进行参数验证,通过这种方式可以降低controller的复杂度,使用方便。

常见的特性有: RequiredAttribute、RangeAttribute等...

而在.net core api中可以看到这些特性依然被保存了下来,接下来就通过使用这些特性来看看.net core api是如何进行校验的。

首先,在控制器中添加一个测试方法,和一个测试action

[HttpPost]
public Info Tets([FromBody] Info data)
{
return data;
} public class Info
{
[Required]
public bool Data { get; set; }
}

然后不传参数(空对象)来测试这个接口:

<response>

HTTPStatus : 400 Bad Request

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|8abecfa7-47340a71b12754df.",
"errors": {
"Data": [
"The Data field is required."
]
}
}

直接返回400,Action不用做多余的处理,这样的话对于简单的验证,我们可以直接在模型里面打标记,action只关注业务,错误码也不用特意去定义,真是一举多得。

如何扩展?

虽然官方已经提供了一些验证特性,但是对于一些其他简单校验,我们可能还是要自己写验证,那么如何去实现自定义的特性验证呢?

查看RequiredAttribute定义:

public class RequiredAttribute : ValidationAttribute

1.继承ValidationAttribute,通过此特性标记当前特性是一个验证特性,在请求时会触发此类的实现

public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
if (!AllowEmptyStrings)
{
string text = value as string;
if (text != null)
{
return text.Trim().Length != 0;
}
}
return true;
}

2.可以看到这里实现了IsValid方法,然后通过返回值的true or false 来表示是否验证成功

接下来,让我们来实现一个简单的例子:传入的集合不能为空且必须有子项

public class CollectionRequiredAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null)
return false;
if (value is ICollection collection)
if (collection.Count == 0) return false;
return true;
}
}

测试成功. 不符合时返回结果:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|c04340c0-41f44630c5a43e25.",
"errors": {
"Arr": [
"The field Arr is invalid."
]
}
}

有的时候,我们可能会想要把错误信息显示得更明显一些,可以提供实现父类方法实现:

public override string FormatErrorMessage(string name)
{
return "你想要返回的消息格式";
}

以上例子都只是一个列的验证,如果你想要类型于CompareAttribute那种多个列进行验证的,该如何实现?

查看CompareAttribute源码:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
PropertyInfo runtimeProperty = validationContext.ObjectType.GetRuntimeProperty(OtherProperty);
if (runtimeProperty == null)
{
return new ValidationResult(System.SR.Format(System.SR.CompareAttribute_UnknownProperty, OtherProperty));
}
if (runtimeProperty.GetIndexParameters().Any())
{
throw new ArgumentException(System.SR.Format(System.SR.Common_PropertyNotFound, validationContext.ObjectType.FullName, OtherProperty));
}
object value2 = runtimeProperty.GetValue(validationContext.ObjectInstance, null);
if (!object.Equals(value, value2))
{
if (OtherPropertyDisplayName == null)
{
OtherPropertyDisplayName = GetDisplayNameForProperty(runtimeProperty);
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}

可以看到它实现了另外一个IsValid,然后通过ValidationContext获取信息进行校验。

返回值说明 : null - 验证通过

实现都非常简单,直接来看例子: 当另外一个字段的值为true时,当前字段不能为null

public class MustDefinedWithPrevAttribute : ValidationAttribute
{ public string PrevCol { get; set; } // 另外一个字段的字段名,用于反射获取值 public MustDefinedWithPrevAttribute(string prevCol, string errorMessage)
{
PrevCol = prevCol;
ErrorMessage = errorMessage; // 指定错误信息
} protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{ var type = validationContext.ObjectInstance.GetType(); if (type.GetProperty(PrevCol).GetValue(validationContext.ObjectInstance) is bool flag && flag)// 另外一个字段值为true
{
if(value == null)
return new ValidationResult(ErrorMessage); // 为空返回验证失败。
}
return null;
}
}

.net core api 对于FromBody的参数验证的更多相关文章

  1. ASP.NET Core MVC 2.1 顶级参数验证

    本文讨论ASP.NET Core 2.1中与ASP.NET Core MVC / Web API控制器中的模型绑定相关的功能.虽说这是一个功能,但从我的角度来看,它更像是一个错误修复! 请注意,我使用 ...

  2. ASP.NET Web API 2 之参数验证

    Ø  前言 目前 C# 比较流行使用 ASP.NET Web API 来承载 Web 接口,提供与客户端之间的数据交互,现在的版本已经是 2.0 了.既然是接口就少不了对输入参数的验证,所以本文主要探 ...

  3. ASP.NET Core API 接收参数去掉烦人的 [FromBody]

    在测试ASP.NET Core API 项目的时候,发现后台接口参数为类型对象,对于PostMan和Ajax的Post方法传Json数据都获取不到相应的值,后来在类型参数前面加了一个[FromBody ...

  4. 【从零开始搭建自己的.NET Core Api框架】(四)实战!带你半个小时实现接口的JWT授权验证

    系列目录 一.  创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...

  5. 自动化CodeReview - ASP.NET Core请求参数验证

    自动化CodeReview系列目录 自动化CodeReview - ASP.NET Core依赖注入 自动化CodeReview - ASP.NET Core请求参数验证 参数验证实现 在做服务端开发 ...

  6. ASP.NET CORE API Swagger+IdentityServer4授权验证

    简介 本来不想写这篇博文,但在网上找到的文章博客都没有完整配置信息,所以这里记录下. 不了解IdentityServer4的可以看看我之前写的入门博文 Swagger 官方演示地址 源码地址 配置Id ...

  7. 详解ASP.NET Core API 的Get和Post请求使用方式

    上一篇文章帮助大家解决问题不彻底导致博友使用的时候还是遇到一些问题,欢迎一起讨论.所以下面重点详细讲解我们常用的Get和Post请求( 以.net core2.2的Http[Verb]为方向 ,推荐该 ...

  8. ASP NET Core ---POST, PUT, PATCH, DELETE,Model 验证

    参照 草根专栏- ASP.NET Core + Ng6 实战:https://v.qq.com/x/page/u0765jbwc6f.html 一.POST 安全性和幂等性 安全性是指方法执行后并不会 ...

  9. 小范笔记:ASP.NET Core API 基础知识与Axios前端提交数据

    跟同事合作前后端分离项目,自己对 WebApi 的很多知识不够全,虽说不必要学全栈,可是也要了解基础知识,才能合理设计接口.API,方便与前端交接. 晚上回到宿舍后,对 WebApi 的知识查漏补缺, ...

随机推荐

  1. python 列表指导式

    >>> a=[page for page in range(10)]>>> print (a)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>& ...

  2. session过期跳转到登陆页面并解决跳出iframe问题

    首先,先转载如下这篇博主写的关于后台系统使用iframe不能跳出的问题,地址:https://blog.csdn.net/xiaocen99/article/details/38521649 在ifr ...

  3. ES6 模块export import

    在 ES6 前, 实现模块化使用的是 RequireJS 或者 seaJS(分别是基于 AMD 规范的模块化库, 和基于 CMD 规范的模块化库).ES6 引入了模块化,其设计思想是在编译时就能确定模 ...

  4. Easyui动态添加控件无法渲染 $.parser.parse()无效

    本文链接:https://blog.csdn.net/huangbaokang/article/details/78367553动态添加easyui控件<input class="ea ...

  5. ecshop二次开发笔记--订单表结构ecs_order_info说明

    -- 表的结构 `ecs_order_info`  CREATE TABLE IF NOT EXISTS `ecs_order_info` (  `order_id` mediumint(8) uns ...

  6. Linux chgrp命令的使用

    Linux chgrp(change group)命令用于变更文件或目录的所属群组. 语法 chgrp [-cfhRv][--help][--version][所属群组][文件或目录...] 或 ch ...

  7. java正则匹配字符串例子

    import java.util.regex.Matcher;import java.util.regex.Pattern; public class sss { public static void ...

  8. 创建函数,传递一个数字n,返回斐波那契数列的第n的值。

    斐波那契数列 第1项和第2项的值是1,从第3项开始,每项的值是前两项相加的和 1   1   2    3    5    8    13    21...... 法1: function fn(n) ...

  9. 软件安装管理(RPM)

    目录 一.linux应用程序 1.1 应用程序与系统命令关系 1.2 典型应用程序的目录结构 1.3 常见的软件包封装工具 二.RPM软件包管理工具 2.1RPM软件包管理器Red-Hat Packa ...

  10. 未知高度-纯css实现水平垂直居中

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...