ASP.NET Web API 2 之参数验证
Ø 前言
目前 C# 比较流行使用 ASP.NET Web API 来承载 Web 接口,提供与客户端之间的数据交互,现在的版本已经是 2.0 了。既然是接口就少不了对输入参数的验证,所以本文主要探讨下,Web API 中实现接口参数验证的几种方式:
1. 使用 Web API 过滤器验证。
2. 继承验证基类,重写验证方法。
1. 使用 Web API 过滤器验证(Demo 演示)
1) 定义个 DataRecordValidationAttribute 类,:默认;1:成交时间由近到远;2:成交金额由高到低;3:成交可能性由高到低;4:过期未成交优先)。
/// </summary>
public int OrderBy { get; set; }
public override bool Validate(ref string message)
{
if (base.Validate(ref message))
{
if (OrderBy < 0 || OrderBy > 4)
message = "排序Key 必须介于 0 至 4 之间";
}
return string.IsNullOrEmpty(message);
}
}
3) 定义参数验证过滤器
/// <summary>
/// 参数验证。
/// </summary>
public class ParameterValidateAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
/// <summary>
/// 在调用操作方法之前发生。
/// </summary>
/// <param name="actionContext">操作上下文。</param>
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
string validateMessage = this.GetValidateMessage(actionContext);
if (!string.IsNullOrEmpty(validateMessage))
{
//var response = new ResponseModel<object>(ResponseStatusCode.ParameterError, validateMessage, null);
//actionContext.Response = actionContext.Request.CreateResponse<ResponseModel<object>>(
// HttpStatusCode.OK, response);
actionContext.Response = actionContext.Request.CreateResponse<string>(HttpStatusCode.BadRequest, validateMessage);
}
base.OnActionExecuting(actionContext);
}
/// <summary>
/// 根据 System.Web.Http.Controllers.HttpActionContext 对象,获取请求参数 RequestModel 派生对象的验证信息。
/// </summary>
/// <param name="actionContext">System.Net.Http.HttpRequestMessage 对象。</param>
/// <returns>验证信息。返回空表示验证成功,否则验证失败。</returns>
public string GetValidateMessage(System.Web.Http.Controllers.HttpActionContext actionContext)
{
string result = null;
try
{
Type paraBaseType = typeof(RequestModel);
var parameterList = actionContext.ActionArguments.Values.ToList();
if (parameterList == null || parameterList.Count != 2) //参数数量不满足,则退出验证
return result;
var parameter = parameterList[1];
if(parameter == null) //只有一个参数时,例如:(HttpRequestMessage request)
return result;
Type parameterType = parameter.GetType();
if (parameter is RequestModel) //参数的基类型不为 RequestModel,则退出验证
{
//递归验证参数
Func<object, string, string> validate = null;
validate = (obj, mes) =>
{
var requestModel = obj as RequestModel;
if (obj != null)
{
if (requestModel.Validate(ref mes)) //为flase时,立即结束验证
{
var properties = obj.GetType().GetProperties();
foreach (var item in properties)
{
if (item.PropertyType.BaseType == paraBaseType)
{
var propObj = item.GetValue(obj, null);
mes = validate(propObj, mes);
if (!string.IsNullOrEmpty(mes))
break;
}
}
}
}
return mes;
};
result = validate(parameter, string.Empty);
}
}
catch (JsonSerializationException ex)
{
result = "参数序列化异常:{0}{1}".Fmt(
ex.InnerException != null ? ex.InnerException.Message : null, ex.Message);
}
catch (Exception ex)
{
//参数验证本身发生异常
result = "参数验证时发生异常:{0}{1}".Fmt(
ex.InnerException != null ? ex.InnerException.Message : null, ex.Message);
}
return result;
}
}
4) 注册全局验证过滤器,在 WebApiConfig.Register() 方法中加入一行代码即可。
config.Filters.Add(new ParameterValidateAttribute());
5) 添加 Action 操作方法
/// <summary>
/// 获取销售机会分页列表。
/// </summary>
/// <param name="request"></param>
/// <param name="model">分页模型。</param>
/// <returns></returns>
[Route("getSalesOpportunityPagingList")]
[System.Web.Http.HttpPost]
public HttpResponseMessage GetSalesOpportunityPagingList(HttpRequestMessage request, PagingReqModel<SalesOpportunityPagingReqModel> model)
{
return CreateHttpResponse(request, (isPaging) =>
{
return userService.GetSalesOpportunityPagingList(isPaging, base.CurrentUserId, model);
}, (data) =>
{
var response = new ResponseModel<PaginationSet<SalesOpportunityPagingResModel>>(ResponseStatusCode.OK, null, data);
var httpResponse = request.CreateResponse<ResponseModel<PaginationSet<SalesOpportunityPagingResModel>>>(HttpStatusCode.OK, response);
return httpResponse;
});
}
6) OK,下面是调用示例
1. 调用失败(排序Key 不在范围内)

2. 调用成功

Ø 总结
1. 使用 Web API 过滤器验证
1) 优点
1. 属于 Web API 框架的一部分,应该性能较好,是一套标准化的验证机制。
2. 支持多种验证规则,例如:数据类型、邮箱、电话号码、数值范围、字符串长度、正则表达式等验证。
2) 缺点
1. 学习成本较高,比较难以控制全局(除了更进一步的封装)。
2. 有时可能不够灵活。
2. 继承验证基类,重写验证方法
1) 优点
1. 功能强大,简单易用,可自定义任意的验证规则。
2. 具有全局性,可提高一定的开发效率。
2) 缺点
1. 性能方面可能有所降低,因为会不停的反射成员属性,有时还有可能递归调用(这是无法避免的)。
3. 共同点:
1) 都是基于模型验证,且都采用了 System.Web.Http.Filters.ActionFilterAttribute 动作过滤器。
2) 非模型参数时,两者都不能实现验证。
Ø 提示:如果有同学有其他的验证方案,或更高见解,欢迎随时讨论~。
ASP.NET Web API 2 之参数验证的更多相关文章
- 让ASP.NET Web API支持$format参数的方法
在不使用OData的情况下,也可以让ASP.NET Web API支持$format参数,只要在WebApiConfig里添加如下三行红色粗体代码即可: using System; using Sys ...
- [转]让ASP.NET Web API支持$format参数的方法
本文转自:http://www.cnblogs.com/liuzhendong/p/4228592.html 在不使用OData的情况下,也可以让ASP.NET Web API支持$format参数, ...
- ASP.NET Web API中的参数绑定总结
ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...
- ASP.NET Web API 安全筛选器
原文:https://msdn.microsoft.com/zh-cn/magazine/dn781361.aspx 身份验证和授权是应用程序安全的基础.身份验证通过验证提供的凭据来确定用户身份,而授 ...
- 【ASP.NET Web API教程】2.1 创建支持CRUD操作的Web API
原文 [ASP.NET Web API教程]2.1 创建支持CRUD操作的Web API 2.1 Creating a Web API that Supports CRUD Operations2.1 ...
- 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理
原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...
- ASP.NET Web API与Owin OAuth:使用Access Toke调用受保护的API
在前一篇博文中,我们使用OAuth的Client Credential Grant授权方式,在服务端通过CNBlogsAuthorizationServerProvider(Authorization ...
- 【转】ASP.NET WEB API系列教程
from: 西瓜小强 http://www.cnblogs.com/risk/category/406988.html ASP.NET Web API教程(六) 安全与身份认证 摘要: 在实际的项目应 ...
- 【ASP.NET Web API教程】6 格式化与模型绑定
原文:[ASP.NET Web API教程]6 格式化与模型绑定 6 Formats and Model Binding 6 格式化与模型绑定 本文引自:http://www.asp.net/web- ...
随机推荐
- Dynamic CRM 2015学习笔记(5)CRM 2015 导入 OData Query Designer 解决方案
以前一直使用OData Query Designer来生成.验证odata查询字符串,本想把它导入到CRM 2015的环境里,但报错: 到MSDN上发现太老版本的solution确实不能再导入到crm ...
- Nginx-Cluster 构建
nx-Cluster and ReverseProxyServer-----------ReProxy-------------------------Client-----------192.168 ...
- [AH2017/HNOI2017]礼物(FFT)
题目描述 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在她生日的前一 ...
- 洛谷P2704 炮兵阵地
本题过于经典...... 对于这种网格状压DP,套路一波刷表法DFS转移就没了. 三进制状压,0表示当前,上一个都没有.1表示当前无,上一个有.2表示当前有. 转移的条件就是上一行为0,当前不是山地, ...
- Remote debugger is in a background tab which may cause apps to perform slowly. Fix this by foregrounding the tab (or opening it in a separate window).
先上代码: /** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow * ...
- 用tkinter制作签名设计窗口
效果如下: from tkinter import * from tkinter import messagebox import requests import re from PIL import ...
- bcftools或vcftools提取指定区段的vcf文件(extract specified position )
下载安装bcftools 见如下命令: bcftools filter 1000Genomes.vcf.gz --regions 9:4700000-4800000 > 4700000-4800 ...
- hdu 4279"Number"(数论)
传送门 参考资料: [1]:https://www.2cto.com/kf/201308/233613.html 题意,题解在上述参考资料中已经介绍的非常详细了,接下来的内容只是记录一下我的理解: 我 ...
- Haproxy 安装初体验
20180916 haproxy Haproxy简介 Haproxy是一款免费的.快速的和稳定的解决方案,提供HA和LB功能,同时对基于TCP的应用和HTTP的应用进行代理,对于流量很大的web站点来 ...
- (分治法 快速幂)51nod1046 A^B Mod C
1046 A^B Mod C 给出3个正整数A B C,求A^B Mod C. 例如,3 5 8,3^5 Mod 8 = 3. 收起 输入 3个正整数A B C,中间用空格分隔.(1 < ...