webAPI请求消息过滤器
每当制作一个WebAPI,就必然会收到外部很多调用这个API的请求,有时候,我们希望,能从这些外部来的请求中,按照一定条件筛选过滤一下,只将那些我们觉得合法的,有必要回应的请求放进来,一方面挡住那些非法请求,一方面也可以节省服务器应付无效请求的资源
这个时候,我们就需要创建一个过滤器
碰巧,前几年给之前某家公司做webapi的时候,钻研过这部分,刚好让我找到了一个在请求到达controller之前过滤掉的办法
好了,废话不多说,直奔主题,这个过滤器的核心就是一个messageHandler,至于它是怎么起到过滤的作用,这方面的原理,我就不详述了,想知道的同学可以点进下面链接
https://www.cnblogs.com/wk1234/archive/2012/05/07/2486872.html
既然核心是一个messageHandler,那么首先就是要创建一个Handler类,如下图
我给这个Handler类起名叫CustomHandler(当然叫别的名字也可以,这个随个人喜好),接下来,就是核心代码部分
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Net.Http; using System.Net; using System.Threading.Tasks; using System.Text; namespace Cabbeen.EWM.RFWebAPI.Handler { public class CustomHandler: DelegatingHandler { protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { string message = ""; var content = request.Content; string jsonContent = content.ReadAsStringAsync().Result;//用这个方法可以获取请求里的body参数值 if (jsonContent.Length < 10) { //无效请求,直接拒绝 var response = new ResultResponse();//自定义的返回结果类 message = "无效请求 无参数或参数长度不够"; response.Status = HttpStatusCode.Forbidden.ToString(); response.Msg = message; return Task.Factory.StartNew<HttpResponseMessage>(() => { return request.CreateResponse(HttpStatusCode.Forbidden, response); }); } //string method = request.Method.ToString(); //Uri uri = request.RequestUri; //HttpContextBase contextBase = (HttpContextBase)request.Properties["MS_HttpContext"]; //HttpRequestBase requestBase = contextBase.Request; //NameValueCollection querycollection = null; //if (requestBase.HttpMethod == "POST") //{ // querycollection = requestBase.Form; //} //if (requestBase.HttpMethod == "GET") //{ // string querys = requestBase.Url.Query.TrimStart('?'); // StringBuilder querybuilder = new StringBuilder(querys); // querycollection = HttpUtility.ParseQueryString(querybuilder.ToString()); //} //合理请求,顺利放行 return base.SendAsync(request, cancellationToken).ContinueWith((task) => { HttpResponseMessage resp = task.Result as HttpResponseMessage; return resp; }); } } }
注意,代码中的关键部分我都进行了标红,并且我删掉了部分与示例无关的项目代码,你们重点看标红的部分代码应该就大概了解了
代码的处理逻辑很简单:如果身份验证码匹配成功,则通过base.SendAsync继续将请求向下传递,否则返回直接中断请求的传递,直接返回一个响应码为403的响应,指示没有权限。
注意由于SendAsync的返回值需要封装在Task之中,所以需要使用Task.Factory.StartNew将返回值包含在Task中
那么现在,过滤器部分的逻辑已经算是写好了,等于是过滤器已经建好了,接下来,就是要把过滤器安装起来,怎么安装呢
很简单,在App_Start文件夹下的WebApiConfig里面,加一句代码就可以了
在WebApiConfig.cs里面的Register方法里加上一句config.MessageHandlers.Add(new Handler.CustomHandler()); 如下图
这样一来,过滤器就算是装载好了,接下来,赶紧模拟请求断点调试试试效果吧
如果还不行,就试试在HttpApplication.Application_Start中加添加如下语句
GlobalConfiguration.Configuration.MessageHandlers.Add(new Handler.CustomHandler());
HttpApplication.Application_Start方法一般在Global.asax.cs里
不过要注意的是,如果WebApiConfig中已经加载了一次CustomHandler,这里就不能再加载,否则CustomHandler会执行两遍