asp.net mvc 過濾器

 

業務場景

        在實際操做中,常常須要將用戶的操做記錄到日誌中,或者是驗證用戶是否登陸了網站,面對這樣的需求,之前的操做是自定義一個統一的全局方法,而後作處理,在每一個須要的頁面中添加想要的函數調用,這致使了多個頁面中存在了大量重複的代碼,這樣的方式不太符合軟件工程的思想。爲了解決這個問題,mvc爲咱們提供了過濾器來完成對應的功能,經過過濾器,咱們只須要將相應的業務處理代碼寫一次,再在相應的功能處經過特性的方式來使用寫好的過濾器。一句話,咱們能夠用過濾器來分離與業務邏輯無關卻常常須要執行的代碼,既保證業務邏輯的正確性,也保證了代碼的簡潔直觀。html

那咱們可使用哪些過濾器呢,這裏一共有四種過濾器,解釋以下mvc

  1. IActionFilter(方法過濾器):接口名爲[IActionFilter],在控制器方法調用前/後執行
  2. IResultFilter(結果過濾器):接口名爲[IResultFilter],在控制器方法調用完,跳轉至view頁面前/後執行
  3. IAuthorizationFilter(受權過濾器):接口名爲[IauthorizationFilter],全部過濾器中最早執行的
  4. IExceptionFilter(異常處理過濾器):接口名爲[IExceptionFilter],在控制器方法拋出異常時執行

根據這裏的執行順序,咱們能夠在不一樣的需求下自行實現對應的控制器,ide

須要注意的是,除了咱們須要實現對應的過濾器接口外,同時還須要保證對應的過濾器是特性類,函數

這裏咱們能夠經過繼承FilterAttribute類來實現。post

代碼場景

按照MVC約定的方式來命名,過濾器以Attribute來結尾。網站

 public class HelpClassAttribute : FilterAttribute, IActionFilter 
    {
        //     在執行操做方法後調用。
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            
        }
        //     在執行操做方法以前調用。
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "在執行操做方法以前調用。" };
            return;
        } 
    }

而後在HomeController中添加添加特性[HelpClassAttribute]spa

    public class HomeController : Controller
    {
        [HelpClassAttribute]
        public ActionResult Index()
        {
            return View();
        }
    }

點擊調試:3d

這樣子,一個簡單的過濾器就實現了。調試

咱們能夠根據實際的邏輯去重寫本身的過濾器。日誌

另一個比較經常使用的是異常過濾器

1,新建SystemErrorAttribute.cs

須要注意,這裏繼承的是:System.Web.Mvc.HandleErrorAttribute

public class SystemErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);
        //處理錯誤消息,將其跳轉到一個頁面
        string controllerName = (string)filterContext.RouteData.Values["controller"];
        string actionName = (string)filterContext.RouteData.Values["action"];
        //這裏簡單向C盤的test.log寫入了文件
        FileStream fs = new FileStream(@"C:\test.log", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter sw = new StreamWriter(fs);
        sw.BaseStream.Seek(0, SeekOrigin.End);
        string writeText = string.Format("controllerName:[{0}]actionName:[{1}]{2}",
            controllerName, actionName, filterContext.Exception.ToString());
        sw.WriteLine(writeText);
        sw.Flush();
        sw.Close();
        fs.Close();

        /*//這裏是使用log4net來記錄
        log4net.ILog log = log4net.LogManager.GetLogger("controllerName:[" + controllerName + "]actionName:[" + actionName+"]");
        log.Error(filterContext.Exception.ToString());
        */

        //錯誤友好輸出,這裏從新構造了一個ActionResult
        filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "系統錯誤,請聯繫管理員" };
        return;
    }
}

2,在HomeController中添加MyError()

public class HomeController : Controller
{
    [Filters.SystemError]//添加
    public ActionResult MyError()
    {
        //人爲製造一個錯誤
        int a = 1;
        int b = 0;
        return Content((a/b).ToString());
    }
}

3,調試:注意:這裏須要採用Ctrl+F5的方式運行,結果以下:

到這裏,可能會有很大疑問,爲何沒有產生友好提示呢?在過濾器中不是明明有添加友好提示嗎?

先看一下C盤的日誌:test.log

日誌有成功產生。沒有出現友好提示的緣由在於不是正式的環境,VS爲了方便調試,不會隱藏錯誤信息。下面將應用部署到真實的環境中去調試,看結果:

 

 

這下友好提示又出來了。。。

固然對於異常處理過濾器來講,我在每一個Action都來添加特性,仍是很麻煩,這裏咱們就要註冊成爲全局過濾器:

①,打開App_Start文件夾中的FilterConfig.cs

添加:filters.Add(new Filters.SystemErrorAttribute());

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //添加這個
        filters.Add(new Filters.SystemErrorAttribute());

        filters.Add(new HandleErrorAttribute());
    }
}

②,在HomeController去掉[Filters.SystemError]特性,而後發佈,調試結果:結果同樣

 

就這樣,全局異常處理就完成了。

 

 

 

 

原文連接:https://www.cnblogs.com/ives/p/filter.html

                  https://www.cnblogs.com/chuliam/p/studyFilter.html

相關文章
相關標籤/搜索