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会执行两遍

posted @ 2018-03-29 21:49  月井石  阅读(880)  评论(0编辑  收藏  举报