文章出處

回到目錄

MVC的過濾器相信大家都用過,一般用來作權限控制,因為它可以監視你的Action從進入到最后View的渲染,整個過程ActionFilter這個過濾器都參與了,而這給我們的開發帶來了更多的好處,如你可以在進行頁面上進行權限的判斷,在頁面渲染前修改頁面的內容,而第二個功能,就是我們今天要說的。

解決實際問題

今天出現一個問題,在webapi向手機端返回數據時,手機端不能正常解析全角的標點符號,英半角英文符號是可以正確解析的,這時我有了一個想法,就是在頁面輸出之前,對它進行處理,將全角符號替換成半角的,而這個功能你不可能寫在每個Action里,這對任何人來說都是一件悲慘的事,所以,ActionFilter出來了,讓它自動去監視,幫我們解決問題吧!

先看一下全局過濾器的配置

    /// <summary>
    /// 全局過濾器的配置
    /// </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(")", "]");
            };
            //添加響應流過濾器
            filters.Add(new ResponseFilter(aa));

        }
    }

下面是ResponseFilter的代碼,主要實現了對響應流的重寫,注意,你必須在頁面渲染前進行處理,當頁面渲染后,你無法對響應流修改,因為這時的流是只讀流

我的ResponseFilter提供了一個Func的委托,就是讓開發人員都自己的處理策略進行自定義,這樣有效的提高了代碼的重復利用性,如果把處理邏輯寫在過濾器里,那么你的這個響應過濾器就被寫死了,無法擴展和復用

 /// <summary>
    /// Http響應流過濾器,對它進行加工
    /// </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執行前
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
        }
        /// <summary>
        /// view頁面渲染前
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            base.OnResultExecuting(filterContext);
        }
        /// <summary>
        /// view頁面渲染后
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            base.OnResultExecuted(filterContext);
        }
        /// <summary>
        /// action執行后
        /// 在這里修改輸出流
        /// </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


    }

感謝您的閱讀,也感謝對倉儲大叔的支持!

回到目錄


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()