前言

在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. asp网页防止乱码

    <%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%> <%Session.CodePage=65001%> ...

  2. c语言:随机函数应用

    #include <stdio.h> #include <time.h>//声明time 时间不可逆转一直在变 #include <math.h> #include ...

  3. SQLITE数据库不支持远程访问

    SQLITE数据库不支持远程访问 import sqlite3 conn=sqlite3.connect("dailiaq.db") cur=conn.cursor() def c ...

  4. BiPredicate的test()方法

    /** * BiPredicate的test()方法接受两个参数,x和y,具体实现为x.equals(y), * 满足Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的 ...

  5. react-router 基本使用

    # 1. 理解react-router react的一个插件库 专门用来实现一个SPA应用 基于react的项目基本都会用到此库 # 2. 几个重要问题## 1). SPA应用 单页Web应用(sin ...

  6. windows程序快速启动的方式:WIN键+R

    WIN键+R是windows快速启动程序的一种方式,一般能独立运行的程序都能以这种方式启动.如notepad.calc.explorer等程序. 在命令行方式下explorer加上不同的参数,会得到不 ...

  7. UBUNTU 16.04 LTS SERVER 手动升级 MariaDB 到最新版 10.2

    UBUNTU 16.04 LTS SERVER 手动升级 MariaDB 到最新版 10.2 1. 起因 最近因为不同软件的数据问题本来只是一些小事弄着弄着就越弄越麻烦了,期间有这么个需求,没看到有中 ...

  8. pycharm基础使用入门

    pycharm基础使用入门 输出 print函数 print('hello world') 右键选择run或者右上角的三角形运行,可以运行出结果 "E:\all sorts of learn ...

  9. OpenFaaS实战之二:函数入门

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. CentOS下 Django部署 nginx+uWSGI+Django(二)

    该篇内容承接CentOS下 Django部署 uWSGI+Django(一),细节流程可参考此篇内容. 1. 当前系统 CentOS Linux release 7.6.1810 Python 2.7 ...