MVC 过滤器使用 ActionFilterAttribute
? ? ? ? ?在asp.net mvc 中 webapi 和 mvc 處理消息是兩個不同的管道,Asp.net mvc 和 webapi 為我們提供的?ActionFilterAttribute 攔截器,通過 重寫?OnActionExecuting,來 攔截action的請求消息,當執行OnActionExecuting完成以后才真正進入請求的action中,action運行完后又把控制權給了?OnActionExecuted,這個管道機制可以使我們用它來輕松實現 權限認證、日志記錄 ,跨域以及很多需要對全局或者部分請求做手腳的的功能。
大概的流程如下
通過ActionFilterAttribute ,就能攔截action 處理的所有內容,包括請求提交的參數以及返回值。由于asp.net MVC 與webapi ?是兩個完全獨立的管道:
- MVC由System.Web.Mvc.ActionFilterAttribute 來做action請求的攔截。
- webapi 由?System.Web.Http.Filters.ActionFilterAttribute 來處理。
因此攔截action請求是完全不相干的兩個通道,于此同時,當我們需要注冊全局的ActionFilterAttribute ?這兩個也是分開注冊的:
MVC 直接在System.Web.Mvc.GlobalFilterCollection ?這個全局管道里面注冊?ActionFilter ,位置在App_Start目錄>FilterConfig 類>RegisterGlobalFilters 方法 使用參數filters ,?filters.Add(new YourMvcAttribute())?添加你的mvc?ActionFilterAttribute ?。
web?API 在System.Web.Http.Filters 中注冊, 在項目的App_Start 目錄>WebApiConfig類中>Register 方法中加入使用 config參數,?config.Filters.Add(new YourWebApiAttribute());?添加你的 webapi?ActionFilterAttribute?
這樣就可以注冊你的?ActionFilterAttribute ? 成為全局的Filter,系統中請求經過Action 之前或之后 都會被你的ActionFilter 攔下來做處理然后在轉交下去。
好了道理已經講完了,現在開始我自己要實現的 日志記錄功能,
需求是記錄所有訪問webapi action的(請求地址、內容、訪問用戶、提交的參數、返回的結果、以及一些客戶端的信息)
由于MVC 框架 提倡契約編程,在你自定義的Attribute 時,需要遵守契約規范, 【YourFilterName】+Attribute ,所以我的filter名字為? LogAttribute
?一、定義過濾器? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?/// <summary>/// 全局日志過濾器(在WebApiConfig中注冊),每個action執行都會執行該過濾器/// </summary>public class LogAttribute : ActionFilterAttribute{public override void OnActionExecuting(HttpActionContext filterContext){if (!SkipLogging(filterContext)){//獲取action名稱string actionName = filterContext.ActionDescriptor.ActionName;//獲取Controller 名稱string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;//獲取觸發當前方法的Action方法的所有參數?var paramss = filterContext.ActionArguments;string Content = Newtonsoft.Json.JsonConvert.SerializeObject(paramss);LogHelper.GetInstance(" LogFilter").Write(string.Format("OnActionExecuting、控制器:{0},動作:{1},參數:{2}", controllerName, actionName, Content));}base.OnActionExecuting(filterContext);}public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext){if (!SkipLogging(actionExecutedContext.ActionContext)){//獲取action名稱string actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;//獲取Controller 名稱string controllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;//獲取觸發當前方法的Action方法的所有參數?var paramss = actionExecutedContext.ActionContext.ActionArguments;string Content = Newtonsoft.Json.JsonConvert.SerializeObject(paramss);LogHelper.GetInstance(" LogFilter").Write(string.Format("OnActionExecuted、控制器:{0},動作:{1},參數:{2}", controllerName, actionName, Content));}base.OnActionExecuted(actionExecutedContext);}/// <summary>/// 判斷控制器和Action是否要進行攔截(通過判斷是否有NoLogAttribute過濾器來驗證)/// </summary>/// <param name="actionContext"></param>/// <returns></returns>private static bool SkipLogging(HttpActionContext actionContext){return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() || actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any();}}/// <summary>/// 不需要日志記錄的過濾器/// </summary>[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]public class NoLogAttribute : Attribute{}二、在WebApiConfig.cs中注冊全局過濾器? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
public static class WebApiConfig{public static void Register(HttpConfiguration config){config.Filters.Add(new LogAttribute());config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional });}}三、在控制器中使用? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
// GET api/sodetails/5public string Get(int id){return "{\"Value\":\"" + id + "\"}";}[NoLog]public string Post([FromBody]string value) //該action不添加日志信息{return "{\"Value\":\"" + value + "\"}";}四、日志效果? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
2018/5/14 14:11:11636619038710767426 L_Message : OnActionExecuting、控制器:SoDetails,動作:Get,參數:{"id":123} L_Level : INFO L_Folder :? LogFilter L_CreatTime : 2018-05-14 14:11:11.075 L_ServerHostName : sh-ysl-bi-hzq L_ServerHostIP : 10.10.40.5 --------------------------------------- 2018/5/14 14:11:14636619038740781337 L_Message : OnActionExecuted、控制器:SoDetails,動作:Get,參數:{"id":123} L_Level : INFO L_Folder :? LogFilter L_CreatTime : 2018-05-14 14:11:14.078 L_ServerHostName : sh-ysl-bi-hzq L_ServerHostIP : 10.10.40.5 ---------------------------------------?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的MVC 过滤器使用 ActionFilterAttribute的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 技术交流群,期待热爱技术的你加入
- 下一篇: 微信公众号H5跳转小程序