zoukankan      html  css  js  c++  java
  • 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会执行两遍

  • 相关阅读:
    zookeeper 简介
    缓存雪崩 缓存穿透
    SpringCloud实战2-Ribbon客户端负载均衡
    SpringCloud实战1-Eureka
    JVM笔记9-Class类文件结构
    JVM笔记8-虚拟机性能监控与故障处理工具
    JVM笔记7-内存分配与回收策略
    SpringAOP-JDK 动态代理和 CGLIB 代理
    MySQL多数据源笔记5-ShardingJDBC实战
    MySQL多数据源笔记4-Mycat中间件实战
  • 原文地址:https://www.cnblogs.com/mooncher/p/8672685.html
Copyright © 2011-2022 走看看