WebApiClient的接口输入验证
1. 文章目的
随着WebApiClient的不断完善,越来越多开发者选择WebApiClient替换原生的HttpClient,本文将介绍WebApiClient的接口参数输入有效性验证的新特性。
2.DataAnnotations介绍
在asp.net mvc
服务端编程中,我们在创建模型的时候,使用System.ComponentModel.DataAnnotations相关的验证特性,配合mvc框架,可以做前端和后端双向输入验证的效果。
public class UserInfo
{
[Required]
[StringLength(10, MinimumLength = 1)]
public string Account { get; set; }
[Required]
[StringLength(10, MinimumLength = 6)]
public string Password { get; set; }
}
以上的Required就是验证特性,asp.net mvc
在模型绑定的时候,会进行验证一遍,验证结果放在控制器的ModelState属性里面。当然System.ComponentModel.DataAnnotations并不是asp.net mvc
特有的,而是基础库自带的,也就是说任何框架下都是可以使用的。
3. 接口参数值的输入验证
Validator静态类提ValidateObject相关的方法,用于验证实例和实例的属性值,WebApiClient使用Validator类来完成接口方法的参数值输入验证:
/// <summary>
/// 提供参数值和参数的属性值输入合法性验证
/// </summary>
static class ParameterValidator
{
/// <summary>
/// 类型的属性否需要验证缓存
/// </summary>
private static readonly ConcurrentCache<Type, bool> cache = new ConcurrentCache<Type, bool>();
/// <summary>
/// 返回是否需要进行属性验证
/// </summary>
/// <param name="instance">实例</param>
/// <returns></returns>
private static bool IsNeedValidateProperty(object instance)
{
if (instance == null)
{
return false;
}
var type = instance.GetType();
if (type == typeof(string) || type.GetTypeInfo().IsValueType == true)
{
return false;
}
return cache.GetOrAdd(type, t => t.GetProperties().Any(p => p.CanRead && p.IsDefined(typeof(ValidationAttribute), true)));
}
/// <summary>
/// 验证参数值输入合法性
/// 验证参数的属性值输入合法性
/// </summary>
/// <param name="parameter">参数描述</param>
/// <param name="validateProperty">是否验证属性值</param>
/// <exception cref="ValidationException"></exception>
public static void Validate(ApiParameterDescriptor parameter, bool validateProperty)
{
var name = parameter.Name;
var instance = parameter.Value;
foreach (var validation in parameter.ValidationAttributes)
{
validation.Validate(instance, name);
}
if (validateProperty == true && IsNeedValidateProperty(instance) == true)
{
var ctx = new ValidationContext(instance) { MemberName = name };
Validator.ValidateObject(instance, ctx, true);
}
}
}
4.接口参数的DataAnnotations声明
4.1 声明参数值的验证
例如GetByIdAsync方法有个id的参数,服务器要求必填且最大长度为10的字符串,我们可以使用Required, StringLength(10)特性修饰id这个参数,在接口调用时,WebApiClient会对id值进行验证,如果不通过则抛出ValidationException的异常。
// /GET webapi/user/GetById?id=id001
// Return HttpResponseMessage
[HttpGet("webapi/user/GetById/{id}")]
[BasicAuth("userName", "password")]
ITask<HttpResponseMessage> GetByIdAsync(
[Required, StringLength(10)] string id);
4.2 声明参数值的属性验证
对于自定义的模型类型,只要在属性里声明了相关的DataAnnotations,WebApiClient就自动进行属性的输入验证。
public class UserInfo
{
[Required]
[StringLength(10, MinimumLength = 1)]
public string Account { get; set; }
[Required]
[StringLength(10, MinimumLength = 6)]
public string Password { get; set; }
}
// POST webapi/user/UpdateWithJson
// Body {"Account":"laojiu","Password":"123456"}
// Return json或xml内容
[HttpPost("webapi/user/UpdateWithJson")]
ITask<UserInfo> UpdateWithJsonAsync(
[JsonContent("yyyy-MM-dd HH:mm:ss")] UserInfo user);
当user参数不为null的情况,就会验证它的Account和Password两个属性。
4.3 声明参数值、参数的属性值同时验证
对于4.2的例子,如果我们希望user参数值也不能为null,可以如下声明方法:
// POST webapi/user/UpdateWithJson
// Body {"Account":"laojiu","Password":"123456"}
// Return json或xml内容
[HttpPost("webapi/user/UpdateWithJson")]
ITask<UserInfo> UpdateWithJsonAsync(
[Required][JsonContent("yyyy-MM-dd HH:mm:ss")] UserInfo user);
5. 禁用参数的属性验证
如果你的模型的属性已声明验证特性,但不希望WebApiClient进行属性值验证,可以在创建接口实例的时候,在配置项里禁用属性验证:
var config = new HttpApiConfig
{
UseParameterPropertyValidate = false
};
var client = HttpApiClient.Create<IUserApi>(config);
6. 结束语
博主为WebApiClient库的作者,本文向读者介绍了DataAnnotations验证特性在WebApiCiient下的使用方法,欢迎大家给WebApiClient提建议。
WebApiClient的接口输入验证的更多相关文章
- Struts2的输入验证
一.概述: ① Struts2的输入验证 –基于 XWorkValidation Framework的声明式验证:Struts2提供了一些基于 XWork Validation Framework的内 ...
- silverlight wpf Command提交时输入验证
silverlight 或WPF在MVVM模式中使用INotifyDataErrorInfo接口对输入进行验证时 控件lostFocus时会触发验证,但在提交动作(例如button的Command)时 ...
- 116-基于5VLX110T FPGA FMC接口功能验证6U CPCI平台 光纤PCIe卡
基于5VLX110T FPGA FMC接口功能验证6U CPCI平台 一.板卡概述 本板卡是Xilinx公司芯片V5系列芯片设计信号处理板卡.由一片Xilinx公司的XC5VLX110T-1FF113 ...
- Struts2入门(四)——数据输入验证
一.前言 1.1.什么是输入验证?为什么需要输入验证? 在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我 ...
- EF里如何定制实体的验证规则和实现IObjectWithState接口进行验证以及多个实体的同时验证
之前的Code First系列文章已经演示了如何使用Fluent API和Data Annotation的方式配置实体的属性,比如配置Destination类的Name属性长度不大于50等.本文介绍E ...
- javascript设计模式实践之策略模式--输入验证
策略模式中的策略就是一种算法或者业务规则,将这些策略作为函数进行封装,并向外提供统一的调用执行. 先定义一个简单的输入表单: <!DOCTYPE html> <html> &l ...
- struts2输入验证
1.方法 ① 基于Annotations的验证 ②基于XML配置的验证 http://blog.csdn.net/furongkang/article/details/692204 ...
- AngularJS学习之输入验证
1.AngularJS可以验证表单和控件可以验证输入的数据: 2.输入验证:客户端不能确保用户输入数据的安全,所以服务器端的数据验证也是必须的: 3.应用实例: <! DOCTYPE html& ...
- [原创]java WEB学习笔记70:Struts2 学习之路-- 输入验证,声明式验证,声明是验证原理
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- bzoj 2002 弹飞绵羊 分块
正解lct,然而本蒟蒻并不会.... 分块思路很清晰,处理出每个点弹出所在块所需要的步数及出去后的第一个位置 #include<cstdio> #include<cstring> ...
- BZOJ_1098_[POI2007]办公楼biu_链表优化BFS
BZOJ_1098_[POI2007]办公楼biu_链表优化BFS Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的 电话号 ...
- BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图
BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图 Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大. ...
- kali下安装截图软件
安装截图软件 1.下载安装python-xlib apt-get install python-xlib 2.下载截图软件包 wget http://packages.linuxdeepin.com/ ...
- TensorFlow之DNN(一):构建“裸机版”全连接神经网络
博客断更了一周,干啥去了?想做个聊天机器人出来,去看教程了,然后大受打击,哭着回来补TensorFlow和自然语言处理的基础了.本来如意算盘打得挺响,作为一个初学者,直接看项目(不是指MINIST手写 ...
- 【.NET异步编程系列3】取消异步操作
在.Net和C#中运行异步代码相当简单,因为我们有时候需要取消正在进行的异步操作,通过本文,可以掌握 通过CancellationToken取消任务(包括non-cancellable任务). 早期 ...
- Linux 系统调用过程详细分析
内核版本:Linux-4.19 操作系统通过系统调用为运行于其上的进程提供服务. 那么,在应用程序内,调用一个系统调用的流程是怎样的呢? 我们以一个假设的系统调用 xyz() 为例,介绍一次系统调用的 ...
- myeclipse附加源码进行查看的方法
在编程过程中,有可能需要用到看源码的情况,那么怎么进行添加源码呢,这里做下记录 首先,先下载javaEE源码(可在网上自由下载) 1.在HttpServlet上右键-->Open Declara ...
- Sharepoint模态窗体(实战)
分享人:广州华软 无名 一. 前言 对SharePoint二次开发时,需要知道SharePoint有什么.没有什么,才能在开发过程中避免重复造轮子.SharePoint提供了许多开箱即用的功能,这次要 ...
- 第一章 渲染调度来龙去脉——插入自己的shader
总有人会问,这个或者那个功能怎么弄,或者看到别人做了什么酷炫的效果也想仿造.其实,功能的实现无非两种: 1.调用Cesium现有的API组合实现:往往照猫画虎,还存在性能不过关的问题,绕了半天其实终究 ...