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 1002】: [FJOI2007]轮状病毒
题目大意:(略) 题解: 第一眼,这不是矩阵树裸体,看了看样例,心想3就有16,那100岂不是要上天…… 果然炸long long……emmmm该不会要打高精除吧……害怕,按照老师的话,不可能考高精除 ...
- 为什么说JAVA中要慎重使用继承
JAVA中使用到继承就会有两个无法回避的缺点: 打破了封装性,迫使开发者去了解超类的实现细节,子类和超类耦合. 超类更新后可能会导致错误. 继承打破了封装性 关于这一点,下面是一个详细的例子(来源于E ...
- 从Java继承类的重名static函数浅谈解析调用与分派
在java中,static成员函数是否可以被重写呢? 结论是,你可以在子类中重写一个static函数,但是这个函数并不能像正常的非static函数那样运行. 也就是说,虽然你可以定义一个重写函数,但是 ...
- Dropwizard入门及开发步骤
Dropwizard介绍 Dropwizard结构的服务组成 开发步骤 Dropwizard介绍 Dropwizard是一个微服务框架, 是各项技术的一个集成封装.它包含了以下组件: 嵌入式Jetty ...
- Mtcnn进行人脸剪裁和对齐B
Mtcnn进行人脸剪裁和对齐 from scipy import misc import tensorflow as tf import detect_face import cv2 # import ...
- 在ASP.NET Core中给上传图片功能添加水印
在传统的.NET框架中,我们给图片添加水印有的是通过HttpModules或者是HttpHandler,然后可以通过以下代码添加水印: var image = new WebImage(imageBy ...
- SqlServer 将纯数字的时间转换为DateTime
由于数据库存的是整个字符串组到一起了,C#代码是这个样子的. public static string time(DateTime dt) { ) ? ) ? ) ? ) ? ) ? " + ...
- WinForm加载外部类库项目的集成开发模式
在项目开发中有一定的团队用到了Nuget.Coding:但是这用起来还是不太方方便,在Winform中呢,我们可以把一个人的项目当作一个类库项目,因为它生成的是一个dll文件,也就是单一文件,拥有了它 ...
- 基于springboot搭建的web系统架构
从接触springboot开始,便深深的被它的简洁性深深的折服了,精简的配置,方便的集成,使我再也不想用传统的ssm框架来搭建项目,一大堆的配置文件,维护起来很不方便,集成的时候也要费力不少.从第一次 ...
- 解放程序员双手之Supervisor
前言 对于大部分程序员来说,主要工作都是进行编码以及一些简单的中间件安装,这就导致了很多人对于“运维”相关的工作会比较生疏.例如当我们拥有一台自己的服务器以后,可能会在上面跑一跑自己blog程序, ...