愛上(shang)MVC系(xi)列~過濾器實現對(dui)響(xiang)應流的處理
MVC的(de)(de)(de)過濾器(qi)相信大家都用(yong)過,一般用(yong)來(lai)(lai)作權限控制,因為它可以監視你的(de)(de)(de)Action從進(jin)入到(dao)最后View的(de)(de)(de)渲染,整個過程ActionFilter這個過濾器(qi)都參與了(le),而(er)這給(gei)我們(men)的(de)(de)(de)開發帶來(lai)(lai)了(le)更多的(de)(de)(de)好處,如你可以在(zai)進(jin)行頁面(mian)上進(jin)行權限的(de)(de)(de)判斷,在(zai)頁面(mian)渲染前(qian)修改頁面(mian)的(de)(de)(de)內容(rong),而(er)第(di)二個功能,就是我們(men)今天要說的(de)(de)(de)。
解決實際問題
今(jin)天出現(xian)一個問(wen)題(ti),在webapi向手機端返回數據時,手機端不能正常解(jie)析全角(jiao)的標點符號(hao),英半角(jiao)英文符號(hao)是(shi)可以正確解(jie)析的,這時我(wo)有了(le)一個想法,就是(shi)在頁(ye)面輸出之(zhi)前,對它進(jin)行處理(li),將全角(jiao)符號(hao)替換成半角(jiao)的,而這個功能你(ni)不可能寫在每個Action里,這對任何人(ren)來說都是(shi)一件悲(bei)慘的事,所以,ActionFilter出來了(le),讓它自(zi)動去監視(shi),幫我(wo)們解(jie)決問(wen)題(ti)吧!
先看一下全局過濾器(qi)的配置
/// <summary> /// 全局過濾器的配置(zhi) /// </summary> public class FilterConfig { /// <summary> /// 注冊全局的過濾器 /// </summary> /// <param name="filters"></param> public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); //響應流處理程序 Func<string, string> aa = (str) => { return str.Replace("(", "[").Replace(")", "]"); }; //添加響(xiang)應流過(guo)濾器 filters.Add(new ResponseFilter(aa)); } }
下面是ResponseFilter的代碼,主要實現了對響應流的重寫,注意,你必須在頁面渲染前進行處理,當頁面渲染后,你無法對響應流修改,因為這時的流是只讀流!
我的ResponseFilter提供了一個Func的委托,就是讓開發人員都自己的處理策略進行自定義,這樣有效的提高了代碼的重復利用性,如果把處理邏輯寫在過濾器里,那么你的這個響應過濾器就被寫死了,無法擴展和復用
/// <summary> /// Http響應(ying)流過濾(lv)器(qi),對它進行加工(gong) /// </summary> public class ResponseFilter : ActionFilterAttribute { /// <summary> /// 輸出流處理程序 /// </summary> Func<string, string> _process; #region Contructors public ResponseFilter() : this(null) { } public ResponseFilter(Func<string, string> process) { this._process = process; } #endregion #region Override Methods /// <summary> /// action執行前(qian) /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); } /// <summary> /// view頁(ye)面渲(xuan)染前 /// </summary> /// <param name="filterContext"></param> public override void OnResultExecuting(ResultExecutingContext filterContext) { base.OnResultExecuting(filterContext); } /// <summary> /// view頁(ye)面(mian)渲染后 /// </summary> /// <param name="filterContext"></param> public override void OnResultExecuted(ResultExecutedContext filterContext) { base.OnResultExecuted(filterContext); } /// <summary> /// action執行(xing)后(hou) /// 在這里(li)修改輸出流 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuted(ActionExecutedContext filterContext) { if (filterContext.Result.GetType() == typeof(JsonResult)) { var aa = ((System.Web.Mvc.JsonResult)(filterContext.Result)).Data; JavaScriptSerializer jss = new JavaScriptSerializer(); var str = jss.Serialize(aa); if (this._process != null) { //處理輸出流 str = this._process(str); ((System.Web.Mvc.JsonResult)(filterContext.Result)).Data = jss.Deserialize<object>(str); } } if (filterContext.Result.GetType() == typeof(ContentResult)) { ((System.Web.Mvc.ContentResult)(filterContext.Result)).Content += "大叔"; } base.OnActionExecuted(filterContext); } #endregion }
感(gan)謝您的(de)閱讀,也感(gan)謝對倉儲(chu)大叔的(de)支(zhi)持!