Asp.net webapi 使用特性拦截请求

214 阅读2分钟

实现功能

根据需要对每个接口增加返回日志记录(相当于java中自定义注解作用在接口上)

思考: 但是asp.net webapi 没有自带使用aop框架,.net core有但这不是所以使用自带过滤器进行拦截做其他处理。(新人基础不牢)

实现自定义Filter


using StandardSchedulingInterface.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace StandardSchedulingInterface.Controllers.hggc
{
    public class LoggingAttribute : ActionFilterAttribute
    {

        public string MethodName { set; get; }

        /// <summary>
        /// 执行后
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            //获取action名称
            string actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
            //获取Controller 名称
            string controllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            // 接口返回时日志记录
            VMBase_Nav.LoggingAction(actionName, GetRequestValues(actionExecutedContext), GetResponseValues(actionExecutedContext));

            base.OnActionExecuted(actionExecutedContext);
        }

        /// <summary>
        /// 执行前
        /// </summary>
        /// <param name="actionContext"></param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            base.OnActionExecuting(actionContext);
        }


        /// <summary>
        /// 读取request 的提交内容
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <returns></returns>
        public string GetRequestValues(HttpActionExecutedContext actionExecutedContext)
        {

            Stream stream = actionExecutedContext.Request.Content.ReadAsStreamAsync().Result;
            Encoding encoding = Encoding.UTF8;
            /*
                这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
                因为你关掉后,后面的管道  或拦截器就没办法读取了
            */
            var reader = new StreamReader(stream, encoding);
            string result = reader.ReadToEnd();
            /*
            这里也要注意:   stream.Position = 0;
            当你读取完之后必须把stream的位置设为开始
            因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
            */
            stream.Position = 0;
            return result;
        }

        /// <summary>
        /// 读取action返回的result
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <returns></returns>
        public string GetResponseValues(HttpActionExecutedContext actionExecutedContext)
        {
            Stream stream = actionExecutedContext.Response.Content.ReadAsStreamAsync().Result;
            Encoding encoding = Encoding.UTF8;
            /*
            这个StreamReader不能关闭,也不能dispose, 关了就傻逼了
            因为你关掉后,后面的管道  或拦截器就没办法读取了
            */
            var reader = new StreamReader(stream, encoding);
            string result = reader.ReadToEnd();
            /*
            这里也要注意:   stream.Position = 0; 
            当你读取完之后必须把stream的位置设为开始
            因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。
            */
            stream.Position = 0;
            return result;
        }

    }
    
}

注册自定Filter

  • 请求接口方法上使用特性 ([Logging])
  • 在接口类上Controller使用特性
  • 全局注册 找到App_Start\WebApiConfig.cs,在Register方法下加入Filter实例:
public static void Register(HttpConfiguration config)
{
     config.MapHttpAttributeRoutes();
    //注册全局Filter
     config.Filters.Add(new LoggingAttribute());

     config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
}