MVC 过滤器使用 ActionFilterAttribute
? ? ? ? ?在asp.net mvc 中 webapi 和 mvc 處理消息是兩個(gè)不同的管道,Asp.net mvc 和 webapi 為我們提供的?ActionFilterAttribute 攔截器,通過(guò) 重寫(xiě)?OnActionExecuting,來(lái) 攔截action的請(qǐng)求消息,當(dāng)執(zhí)行OnActionExecuting完成以后才真正進(jìn)入請(qǐng)求的action中,action運(yùn)行完后又把控制權(quán)給了?OnActionExecuted,這個(gè)管道機(jī)制可以使我們用它來(lái)輕松實(shí)現(xiàn) 權(quán)限認(rèn)證、日志記錄 ,跨域以及很多需要對(duì)全局或者部分請(qǐng)求做手腳的的功能。
大概的流程如下
通過(guò)ActionFilterAttribute ,就能攔截action 處理的所有內(nèi)容,包括請(qǐng)求提交的參數(shù)以及返回值。由于asp.net MVC 與webapi ?是兩個(gè)完全獨(dú)立的管道:
- MVC由System.Web.Mvc.ActionFilterAttribute 來(lái)做action請(qǐng)求的攔截。
- webapi 由?System.Web.Http.Filters.ActionFilterAttribute 來(lái)處理。
因此攔截action請(qǐng)求是完全不相干的兩個(gè)通道,于此同時(shí),當(dāng)我們需要注冊(cè)全局的ActionFilterAttribute ?這兩個(gè)也是分開(kāi)注冊(cè)的:
MVC 直接在System.Web.Mvc.GlobalFilterCollection ?這個(gè)全局管道里面注冊(cè)?ActionFilter ,位置在App_Start目錄>FilterConfig 類(lèi)>RegisterGlobalFilters 方法 使用參數(shù)filters ,?filters.Add(new YourMvcAttribute())?添加你的mvc?ActionFilterAttribute ?。
web?API 在System.Web.Http.Filters 中注冊(cè), 在項(xiàng)目的App_Start 目錄>WebApiConfig類(lèi)中>Register 方法中加入使用 config參數(shù),?config.Filters.Add(new YourWebApiAttribute());?添加你的 webapi?ActionFilterAttribute?
這樣就可以注冊(cè)你的?ActionFilterAttribute ? 成為全局的Filter,系統(tǒng)中請(qǐng)求經(jīng)過(guò)Action 之前或之后 都會(huì)被你的ActionFilter 攔下來(lái)做處理然后在轉(zhuǎn)交下去。
好了道理已經(jīng)講完了,現(xiàn)在開(kāi)始我自己要實(shí)現(xiàn)的 日志記錄功能,
需求是記錄所有訪問(wèn)webapi action的(請(qǐng)求地址、內(nèi)容、訪問(wèn)用戶(hù)、提交的參數(shù)、返回的結(jié)果、以及一些客戶(hù)端的信息)
由于MVC 框架 提倡契約編程,在你自定義的Attribute 時(shí),需要遵守契約規(guī)范, 【YourFilterName】+Attribute ,所以我的filter名字為? LogAttribute
?一、定義過(guò)濾器? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?/// <summary>/// 全局日志過(guò)濾器(在WebApiConfig中注冊(cè)),每個(gè)action執(zhí)行都會(huì)執(zhí)行該過(guò)濾器/// </summary>public class LogAttribute : ActionFilterAttribute{public override void OnActionExecuting(HttpActionContext filterContext){if (!SkipLogging(filterContext)){//獲取action名稱(chēng)string actionName = filterContext.ActionDescriptor.ActionName;//獲取Controller 名稱(chēng)string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;//獲取觸發(fā)當(dāng)前方法的Action方法的所有參數(shù)?var paramss = filterContext.ActionArguments;string Content = Newtonsoft.Json.JsonConvert.SerializeObject(paramss);LogHelper.GetInstance(" LogFilter").Write(string.Format("OnActionExecuting、控制器:{0},動(dòng)作:{1},參數(shù):{2}", controllerName, actionName, Content));}base.OnActionExecuting(filterContext);}public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext){if (!SkipLogging(actionExecutedContext.ActionContext)){//獲取action名稱(chēng)string actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;//獲取Controller 名稱(chēng)string controllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;//獲取觸發(fā)當(dāng)前方法的Action方法的所有參數(shù)?var paramss = actionExecutedContext.ActionContext.ActionArguments;string Content = Newtonsoft.Json.JsonConvert.SerializeObject(paramss);LogHelper.GetInstance(" LogFilter").Write(string.Format("OnActionExecuted、控制器:{0},動(dòng)作:{1},參數(shù):{2}", controllerName, actionName, Content));}base.OnActionExecuted(actionExecutedContext);}/// <summary>/// 判斷控制器和Action是否要進(jìn)行攔截(通過(guò)判斷是否有NoLogAttribute過(guò)濾器來(lái)驗(yàn)證)/// </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>/// 不需要日志記錄的過(guò)濾器/// </summary>[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]public class NoLogAttribute : Attribute{}二、在WebApiConfig.cs中注冊(cè)全局過(guò)濾器? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
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,動(dòng)作:Get,參數(shù):{"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,動(dòng)作:Get,參數(shù):{"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 ---------------------------------------?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的MVC 过滤器使用 ActionFilterAttribute的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 技术交流群,期待热爱技术的你加入
- 下一篇: c语言结构体定义坐标,C/C++知识点之