Asp.Net MVC過濾器小試牛刀

来源:http://www.cnblogs.com/chuliam/archive/2016/02/03/studyFilter.html
-Advertisement-
Play Games

Asp.Net Filter學習,學習了基本過濾器、ActionFilterAttribute以及異常過濾器 當然最後學習了全局異常過濾器 文中有很多拍不足之處,敬請各位諒解


  在上學期間學習的Asp.Net MVC,基本只是大概馬馬虎虎的瞭解,基本處於知其然而不知其所以然。現在到上班,接觸到真實的項目,才發現還不夠用,於是從最簡單的過濾器開始學習。不得不說MVC的過濾器真是簡單,而又不失優雅。

  以前我寫異常都是try...catch...配合log4net來記錄日誌,這真是一個重覆造輪子的過程,一不小心還會忘記。後面在開發的過程中,逐漸學習到過濾器(Filter)這一優雅的東東,一下子愛上了它。

  在Asp.Net MVC有最基本的過濾器,添加一個Home控制器,然後添加兩個Action,這裡為了演示,添加了兩個同名的Action,為了編譯,設置了參數的區別,實際上並沒有使用參數。

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index(string msg)
    {
        return Content("I'm come from Get Method.");
    }

    [HttpPost]
    public ActionResult Index()
    {
        return Content("I'm come from Post Method.");
    }
}

點擊調試,使用PostMan分別用get/post方式去訪問Home/Index,如下圖:

對於同一個Action,只是請求方式不一樣,返回的結果也不一樣,這就是Asp.Net最基本的過濾器。

[HttpGet]:該Action只響應get請求
[HttpPost]:該Action只響應post請求

於是我們可以思考,是不是可以考慮將很多重覆的代碼封裝起來,例如判斷用戶是否有許可權訪問該Action,只需要簡單的在Action上做一個特性標註就可以或者註冊一個全局的機制,滿足需要?很好,Asp.Net給我們提高了簡單優雅的過濾器。

下麵來簡單看一下我自己寫的許可權判斷過濾器。

1,在項目中添加Filters文件夾,所有Filters都放置在該文件夾中,方便後期歸檔

2,在Filters文件夾中添加一個類:CheckUserRoleAttribute.cs,在這裡我們按照MVC約定的方式來命名,過濾器以Attribute來結尾。讓其繼承: System.Web.Mvc.ActionFilterAttribute。查看ActionFilterAttribute定義,其成員如下:

// 摘要: 
//     在執行操作方法後由 ASP.NET MVC 框架調用。
//
// 參數: 
//   filterContext:
//     篩選器上下文。
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
//
// 摘要: 
//     在執行操作方法之前由 ASP.NET MVC 框架調用。
//
// 參數: 
//   filterContext:
//     篩選器上下文。
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
//
// 摘要: 
//     在執行操作結果後由 ASP.NET MVC 框架調用。
//
// 參數: 
//   filterContext:
//     篩選器上下文。
public virtual void OnResultExecuted(ResultExecutedContext filterContext);
//
// 摘要: 
//     在執行操作結果之前由 ASP.NET MVC 框架調用。
//
// 參數: 
//   filterContext:
//     篩選器上下文。
public virtual void OnResultExecuting(ResultExecutingContext filterContext);

看註解可以知道4個成員:

OnActionExecuted
OnActionExecuting
OnResultExecuted
OnResultExecuted

而我一般都是重寫OnActionExecuting方法:

public class CheckUserRoleAttribute : System.Web.Mvc.ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
    {
        /*
         * 這裡為了方便演示,直接在請求參數中獲取了userName
         * 假設某一個Action只有Lucy可以訪問。
         */
        string userName = filterContext.HttpContext.Request["userName"];
        if (userName=="Lucy")
        {
            base.OnActionExecuting(filterContext);
            return;
        }
        else
        {
            //這裡構造了一個心得ActionResult.如果userName不是Lucy,則返回許可權不足
            filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "許可權不足,無法訪問" };
            return;
        }
    }
}

然後在HomeController中添加SayHello(),並且添加特性[CheckUserRole]

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index(string msg)
    {
        return Content("I'm come from Get Method.");
    }

    [HttpPost]
    public ActionResult Index()
    {
        return Content("I'm come from Post Method.");
    }

    //添加特性
    [Filters.CheckUserRole]
    public ActionResult SayHello()
    {
        return Content("我是Lucy,這隻能給我訪問");
    }
}

點擊調試:

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

我們可以根據實際的邏輯去重寫自己的過濾器。

**********************簡單優雅的分隔符**********************

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

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]特性,然後發佈,調試結果:結果一樣

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

 

========================

由於學識有限,文章難免會有錯誤,敬請指教與批評。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、PD虛擬機的安裝1、Parallels Desktop ,簡稱PD,號稱是Mac上最好用的虛擬機,具體的就在此不進行過多描述。下附Mac .app文件夾下載,下載後放入/Applications/文件夾下即可。 安裝完成後如圖 2、打開PD,運行效果如下 運行效果 點擊此處進行下載(後期提供網盤
  • Windows2012安裝IIS和FTP 1、打開Windows 2012的伺服器管理器,選擇 管理→添加角色和功能 2、進入 添加角色和功能嚮導,選擇 “Web伺服器(IIS)” 3、根據情況選擇對應功能,這裡選擇.Net3.5 4、安裝角色服務,選擇對應的安全性選項,如圖: 5、選擇“FTP服務
  • 一、簡介 Redis是一種高級key-value資料庫。它跟memcached類似,不過數據可以持久化,而且支持的數據類型很豐富。有字元串,鏈表,集 合和有序集合。支持在伺服器端計算集合的並,交和補集(difference)等,還支持多種排序功能。所以Redis也可以被看成是一個數據結構服務 器。 ...
  • 由於網速和大中華區域網效果,使得我們在DockerHub下載鏡像的速度很慢,甚至一些國內的鏡像倉庫,也感覺速度不是很好。所以,很有必要在本地或者一個我們訪問很快速的地方(自己的雲伺服器)搭建一套鏡像倉庫。有了這樣一個倉庫,不僅可以提高下載速度,而且可以增加我們個性化定製的鏡像,以備後續使用。這篇將介
  • linux centos 6.5 _64 oracle 11.2g 今天接到一個客戶電話說重啟了伺服器,資料庫沒有重啟來,看了資料庫的報錯 沒有找到control文件的路徑,資料庫啟動到了 unmount狀態 , 因為資料庫是在存儲上放著的,資料庫程式安裝在本機上 , df -h 查看存儲沒有哦掛載
  • 一、分散式緩存簡圖 二、為什麼使用Memcached分散式緩存呢? 三、Memcached基礎原理 四、Memcache下載與安裝 五、MencacheHelper.cs 示例使用 結合Session與項目配置緩存 六、Redis和Memcache的區別總結 一、分散式緩存簡圖 二、為什麼使用Mem
  • 最小數據集(Minimum Data Set,MDS)最小數據集的概念起源於美國的醫療領域,用來統一醫療賬單.最小數據集是指通過收集最少的數據,最好地掌握一個研究對象所具有的特點或一件事情、一份工作所處的狀態,其核心是針對被觀察的對象建立一套精簡實用的數據指標.最小數據集的出現,最早是因為不同組織之
  • 什麼是c#預處理指令?? 用於在 C# 源代碼中嵌入的編譯器命令。 C#預處理器指令有哪些?? ↓↓↓這些就是預處理器指令啦 下麵我們一一道來(●'◡'●) 1.#if ,#elif,#else,endif c#編譯的第一步就是預處理,這一步中,根據源程式中#開頭的指令(預處理指令)進行處理。 例如
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...