ASP.NET WebAPI 11 参数验证
在绑定完Action的所有参数后,WebAPI并不会马上执行该方法,而要对参数进行验证,以保证输入的合法性.
ModelState
在ApiController中一个ModelState属性用来获取参数验证结果.
public abstract class ApiController : IHttpController, IDisposable{public ModelStateDictionary ModelState { get; } }
ApiContext的ModelState属性实际是对每个Action参数验证的结果集合.
public class ModelStateDictionary : IDictionary<string, ModelState>, ICollection<KeyValuePair<string, ModelState>>, IEnumerable<KeyValuePair<string, ModelState>>, IEnumerable{ public int Count { get; } public bool IsReadOnly { get; } public bool IsValid { get; } public ModelState this[string key] { get; set; } public void Add(KeyValuePair<string, ModelState> item); public void Add(string key, ModelState value); }
public class ModelState{ public ModelState(); public ModelErrorCollection Errors { get; } public ValueProviderResult Value { get; set; } }
public class ModelError{public string ErrorMessage { get; } public Exception Exception { get; } }
对于ModelStateDictionary,ModelState,ModelError我们可以理解成Action所有参数(所有参数的属性)的验证结果.单个参数的验证结果.单个参数属性的单个验证结果(一个参数可能有多个难结果).
ModelStateDictionary的IsValid属性表示验证是否通过.另外 Count属性对于不同的参数绑定方式在WebAPI中可能表现不同的结果.这个后面会有具体例子.
ValidationAttribute特性
采用ValidationAttribute特性进行参数验证是WebAPI的默认验证方式.ValidationAttribute位于" System.ComponentModel.DataAnnotations"命名空间下,在这个命名空间下还定义了一些具体的ValidationAttribute,如图:
public abstract class ValidationAttribute : Attribute{public string ErrorMessage { get; set; } public string ErrorMessageResourceName { get; set; } public Type ErrorMessageResourceType { get; set; } public virtual bool RequiresValidationContext { get; } public virtual string FormatErrorMessage(string name); public ValidationResult GetValidationResult(object value, ValidationContext validationContext); public virtual bool IsValid(object value); public void Validate(object value, string name); public void Validate(object value, ValidationContext validationContext); }
ValidationAttribute的IsValid方法用来返回验证是否通过, FormatErrorMessage方法用来返回错误信息.
下面我就自定义一个ArrayValidatorAttribute,用来进行区间判断,即让开发者自定义一个数组,然后判断值是不是在数组内.
public class ArrayValidationAttribute : ValidationAttribute{ public object[] _list; public ArrayValidationAttribute(params object[] list) { _list = list; } public object[] List { get { return _list; } set { _list = value; } } public override bool IsValid(object value) { return _list.Contains(value); } public override string FormatErrorMessage(string name) { return string.Format("{0}不在区间内.", name); } }
CustomerValidationAttribute的使用
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true)] public sealed class CustomValidationAttribute : ValidationAttribute{ public CustomValidationAttribute(Type validatorType, string method); public string Method { get; } public override object TypeId { get; } public Type ValidatorType { get; } public override string FormatErrorMessage(string name); protected override ValidationResult IsValid(object value, ValidationContext validationContext); }
从定义中我们可以看出来CustomerValidationAttribute是不能被继承的,这是说明CustomerValidationAttribute不同于ValidaitionAttribute的使用方式.实际上CustomerValidationAttribute采用的反射的方式去进行验证.它包含了ValidationType,Method两个属性,这两个属性分别表示反射使用到的类与方法名.
对于可以用作验证的方法要满足以下条件:
- 方法是公开的,静态的
- 方法必须要有一个或者两个参数.
- 如果方法只有一个参数,那么这个参数必须是未做ref,out标注的(该参数实际上是要验证的值)
- 如果方法有两个参数,那么第一个参数的约束用3,第二个参数必须是ValidationContext类型
Model绑定与反序列化参数结果对比
Model绑定方式保存了所有的验证结果,反序列化方式只保存了验证未通过的结果
如下:
public ModelStateDictionary PostFigureFromUrlForState([ModelBinder]Figure figure) { return ModelState; } public ModelStateDictionary PostFigureFromBodyForState([FromBody]Figure figure) { return ModelState; }
对于Figure,将LastName,FirstName都设置成必须。
public class Figure{ [Required] public string FirstName { get; set; } [Required]public string LastName { get; set; } }
现在我们对两个方法传相同的数据:{FirstName:null,LastName:"Stack"}
url:
/api/Demo/PostFigureFromUrlForState?LastName=Stack
/api/Demo/PostFigureFromBodyForState
实际得到的结果分别如下:
源码
Github: https://github.com/BarlowDu/WebAPI (API_11)
转载于:https://www.cnblogs.com/gangtianci/p/4951351.html
ASP.NET WebAPI 11 参数验证相关推荐
- 自动化CodeReview - ASP.NET Core请求参数验证
自动化CodeReview系列目录 自动化CodeReview - ASP.NET Core依赖注入 自动化CodeReview - ASP.NET Core请求参数验证 参数验证实现 在做服务端开发 ...
- asp.net webapi 自定义身份验证
/// <summary> /// 验证 /// </summary> /// Account API账号 /// TimeStamp 请求时间 /// Sign 所有请求参数 ...
- nodejs获取ASP.Net WebAPI(IIS Windows验证)
处理了很多天,终于使用Nodejs可以发出请求至WebAPI,能够正常处理数据了 首先加入npm包 npm install httpntlm 在app.js中加入代码 var httpntlm = r ...
- ASP.NET WEBAPI实现微信接入验证
本主题所有内容以软认知服务为技术基础 关于微软人脸识别,请参阅 本节内容请先参阅微软认知服务人脸API接口列表 ##ASP.NET WEBAPI实现微信接入验证 首先你需要一个微信公众号,很重要的是你 ...
- Winform宿主Asp.Net WebApi中Owin 自定义Token请求参数
本文介绍的是Winform宿主Asp.net WebAPI的过程,利用了Microsoft.AspNet.WebApi.OwinSelfHost. Asp.NET WebAPI中的授权验证有很多: 例 ...
- dotNET Core WebAPI 统一处理(返回值、参数验证、异常)
现在 Web 开发比较流行前后端分离 现在 Web 开发比较流行前后端分离,我们的产品也是一样,前端使用Vue,后端使用 dotNet Core WebAPI ,在写 API 的过程中有很多地方需要统 ...
- 使用ASP.Net WebAPI构建REST服务(四)——参数绑定
默认绑定方式 WebAPI把参数分成了简单类型和复杂类型: 简单类型主要包括CLR的primitive types,(int.double.bool等),系统内置的几个strcut类型(TimeSpa ...
- 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi
一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...
- 后台参数验证的几种方式
前言 参数验证是一个常见的问题,无论是前端还是后台,都需对用户输入进行验证,以此来保证系统数据的正确性.对于web来说,有些人可能理所当然的想在前端验证就行了,但这样是非常错误的做法,前端代码对于用户 ...
最新文章
- variant 字符串数组_VB数组部分核心知识总结
- JavaScript (二)
- Spring Security 入门(五):在 Spring-Boot中的应用
- 饿了么高稳定、高性能、高可用、高容错API架构实践!
- python 链表 【测试题】
- c 语言str.size,C/C++ strlen(str)和str.length()和str.size()的区别
- 日常((⊙_⊙)…)
- 【kudu】未解决 Flink 读取 kudu KuduReaderIterator not found it may have expired
- [转]awsome-java
- GT_Trace的使用
- iOS自带的GPS 定位
- daemontools的安装、简介
- Leo:一个outlining editor
- BP网络异或问题C语言实现,bp网络实现xor异或的C语言实现202102
- 零基础如何快速学习Java?Java基础入门秘诀
- codeforces CF1736B Playing with GCD
- Java学习笔记(三十五)
- 婚恋社交项目,寻找创业合伙人,坐标上海
- 【Leetcode 3】无重复字符的最长子串
- 大麦回忆录-maizuo开发
热门文章
- 水题/poj 1852 Ants
- 服务器可以响应字符类型的数据吗,HTTP - Response
- hashids php 如何使用,Hashids使用
- oracle 开始一个事务,oracle的启动与关闭原理-事务commit或者rollback
- stc15w404as引脚图_STC15F2K6S2与stc15w404AS的spi通讯
- paoding java_中文分词器-PaodingAnalyzer
- asp.net mysql 创建变_[ASP.net教程]EF Core使用CodeFirst在MySql中创建新数据库以及已有的Mysql数据库如何使用DB First生成域模型...
- c语言中比较两个数组函数,输入两个数组,调用large函数比较,计数,输出统计结果...
- MySQL面试题 | 附答案解析(十一)
- 2020年全球十大突破性技术公布:数字货币等在列