1. 程式人生 > >ASP.NET MVC學習---(九)許可權過濾機制(完結篇)

ASP.NET MVC學習---(九)許可權過濾機制(完結篇)

相信對許可權過濾大傢伙都不陌生

使用者要訪問一個頁面時

先對其許可權進行判斷並進行相應的處理動作

在webform中

最直接也是最原始的辦法就是

在page_load事件中所有程式碼之前

先執行一個許可權判斷的方法

至於其專業的許可權機制這裡不做討論

想要了解的同學可以自行google之

或者點選進入:

那麼mvc中是如何實現許可權驗證的?

據我們所知

mvc中是根據路由配置來請求控制器類中的一個方法

並沒有webform中的page_load方法

難道我們要在每個action方法中都呼叫一個許可權判斷的方法嗎?

很明顯不可能= =

懶惰的程式設計師們怎麼可能允許這種情況發生

其實在mvc框架中

為程式設計師提供了一種過濾器機制

通過過濾器

我們可以隨心所欲的控制訪問許可權

那麼接下來

教育科學頻道--走近科學帶你進入過濾器的內心世界~~

首先,我們可以自己新增一個過濾器

新增一個類,名為MyFilter1Attribute

並繼承自ActionFilterAttribute類(注意,這裡的ActionFilterAttribute的名稱空間是System.Web.Mvc不要引用錯了~)

現在這個MyFilter1Attribute就是一個過濾器類了

因為繼承自ActionFilterAttribute類

所以我們自己新增的MyFilter1Attribute就擁有了某些過濾方法

我們對ActionFilterAttributeF12轉到定義看一看裡面有什麼東西

可以看到,這個ActionFilterAttribute是一個特性類(這就是人家為什麼以Attribute結尾啦~)

並且實現了兩個很重要的介面IActionFilter,IResultFilter

我們在轉到定義看一下這兩個介面中有什麼

可以看到

這兩個介面中各自定義了兩個方法,而ActionFilterAttribute既然實現了它們,那麼ActionFilterAttribute自然也會擁有這四個方法

那麼這四個方法是什麼呢?

馬上揭曉~

前面我們說到過,ActionFilterAttribute其實是一個特性類

什麼是特性類?

就比如之前進實體驗證的時候,為實體的欄位貼上的標籤

那個標籤就是一個特性類

也就是說

特性類可以通過貼標籤的形式來使用

而我們自己新增的MyFilter1Attribute也是一個特性類

這有什麼用嗎?

等下你就知道了~

現在先在MyFilter1Attribute中重寫OnActionExecuting方法

其實我們可以從這個方法的名字上大概推出這個方法是做什麼的了

沒錯,該方法會在action方法執行之前呼叫

反之IActionFilter中的另一個方法--OnActionExecuted就是在action方法執行完畢之後呼叫

口說無憑

下面上證據:

public class MyFilter1Attribute:ActionFilterAttribute
    {
        //該方法會在action方法執行之前呼叫
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法呼叫錢執行<br/>");
            base.OnActionExecuting(filterContext);
        }

        //該方法會在action方法執行之後呼叫
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在action方法呼叫後執行<br/>");
            base.OnActionExecuted(filterContext);
        }

    }

在Home控制器中新增一個action方法

[MyFilter1]
        public void FilterTest()
        {
             Response.Write("我是action方法,在這裡執行了~~</br>");
        }

這時候看到了嗎?

要在一個action方法中使用一個過濾器

只要在該方法上貼一個過濾器的標籤就ok~ 
生成執行,結果如下:

強有力的證明~

但是呢,有時候我們會有這樣的一需求:

在過濾器中當遇到了貼了某某標籤的action方法就跳過不進行驗證

這怎麼辦呢?

可以通過filterContext的ActionDescriptor屬性類完成這易操作

ActionDescriptor顧名思義,action方法的描述著

在ActionDescriptor中我們可以拿到相應的action方法資訊,甚至還可以拿到一個控制器描述著ControllerDescriptor

程式碼如下:

//該方法會在action方法執行之前呼叫
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法呼叫前執行<br/>");
            //判斷該action方法時候有貼上MyFilter1Attribute標籤
            if (filterContext.ActionDescriptor.IsDefined(typeof (MyFilter1Attribute),false))
            {
                //如果有,為該action方法直接返回ContentResult,則該action方法在這裡就有了返回值,相當於在這裡就結束了,不會在去執行之後的方法,如:OnActionExecuted等
                filterContext.Result = new ContentResult();
            }
            base.OnActionExecuting(filterContext);
        }

結果如圖:

 

可以看到,action方法中和OnActionExecuted中的Response.Write都沒有被執行,也就是說,該action方法被跳過了

之前我們使用的是IActionFilter介面中的方法

接下來介紹IResultFilter介面方法

//在action方法返回結果之後執行
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuted,我action方法返回結果之前執行<br/>");
            base.OnResultExecuting(filterContext);
        }

        //在action方法返回結果之前前執行
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnResultExecuted,我在action方法返回結果之後執行<br/>");
            base.OnResultExecuted(filterContext);
        }


IResultFilter中同樣也有兩個方法

我們將FilterTest改為下面程式碼:

[MyFilter1]
        public ActionResult FilterTest()
        {
            Response.Write("我是action方法的Response.Write,在這裡執行了~~</br>");
            return View();
        }

並新增檢視如下:

<body>
    <div>
        我是FilterTest的檢視,在這裡執行action方法~~
    </div>
</body>

生成並執行,結果圖:

  

可以看到,IResultFilter介面中的方法和IActionFilter方法的區別就是執行位置不一樣

但是呢,mvc框架中還有一個過濾器

他就是許可權過濾器AuthorizeAttribute

該過濾器在所有action方法過濾器之前執行,也就是說,提供了一個可以超前驗證的方法

我們在新增一個新的過濾器類,並繼承自AuthorizeAttribute

重寫其OnAuthorization方法如下:

這裡需要注意,把基類的OnAuthorization方法去掉,因為我們並不需要,而且留著可能會出現一些錯誤異常

public class MyFilter2Attribute:AuthorizeAttribute
    {
        //在所有action方法過濾器之前執行
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnAuthorization,在所有action方法過濾器之前執行<br/>");
            //base.OnAuthorization(filterContext);
        }
    }
[MyFilter1]
        [MyFilter2]
        public ActionResult FilterTest()
        {
            Response.Write("我是action方法的Response.Write,在這裡執行了~~</br>");
            return View();
        }

為FilterTest方法在貼上MyFilter2標籤

執行:

 

有圖有證據~

如此一來

我們就可以根據需要選擇合適的方法進行許可權驗證

但是這時候又有問題了

什麼問題呢?

這個特性是貼在action方法上面的

如果我控制器中所有的action方法都要進行驗證怎麼辦?

難道每個action方法都貼一遍嗎?

如果我程式中的所有控制器中的所有action方法都需要驗證呢?

放心~

懶惰的程式設計師們是不會去做這種傻事的~

如果一個控制器中的所有方法都需要驗證

那麼我們可以再控制器類上統一貼上標籤,如下:

這樣一來該控制器中的所有action方法都會進行驗證

那麼如果每個控制器類都要驗證呢?

這個時候我們就需要開啟App_Start檔案夾了

看到一個FilterConfig類了嗎

雙擊開啟FilterConfig.cs

我們可以再這裡進行新增全域性的過濾器,比如:

最後我們在介紹一個異常處理的過濾器

新增一個過濾器類,並繼承自HandleErrorAttribute

 public class MyFilter3Attribute:HandleErrorAttribute
    {
        //在程式中任何地方出現異常都會執行
        public override void OnException(ExceptionContext filterContext)
        {
            //獲取異常物件
            Exception ex = filterContext.Exception;
            //記錄錯誤日誌
            //導向友好錯誤介面
            filterContext.Result = new RedirectResult("/Home/Index");
            //重要!!告訴系統異常已處理!!如果沒有這個步驟,系統還是會按照正常的異常處理流程走
            filterContext.ExceptionHandled = true;
            //base.OnException(filterContext);
        }
    }


注意,這裡基類的OnException也是不需要的

那麼異常處理的過濾器要放在哪裡呢?

肯定是全域性的呀~

filters.Add(new MyFilter3Attribute());

ok,搞定~

不信你執行看看~

asp.net mvc的入門學習到此就全部結束了~

期待著下一次的進步! 



相關推薦

ASP.NET MVC學習---許可權過濾機制完結

相信對許可權過濾大傢伙都不陌生 使用者要訪問一個頁面時 先對其許可權進行判斷並進行相應的處理動作 在webform中 最直接也是最原始的辦法就是 在page_load事件中所有程式碼之前 先執行一個許可權判斷的方法 至於其專業的許可權機制這裡不做討論 想要了解的同學可以自行

ASP.NET MVC 學習筆記-7.自定義配置信息後續

字符串 return abstract 新的 work 生成 value DC 連接字符串加密 自定義配置信息的高級應用 通過上篇博文對簡單的自定義配置信息的學習,使得更加靈活的控制系統配置信息。實際項目中,這種配置的靈活度往往無法滿足項目的靈活度和擴展性。 比如,一個

ASP.NET MVC學習之Ajax完結

等待 failure lba info 學習 有一個 代碼 orm 修改 網址:https://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_ajax.html 一.前言 通過上面的一番學習,大家一定收獲不少。但是總歸會有一個結束的時候

ASP.Net MVC學習

方法 title 系列 字符串類 所有 value 內部 但是 必須 MVC 設計模式將應用程序分解成3個主要部分: Model, View, Controller(模型、視圖、控制器) Model - 模型代表一系列類用來描述業務邏輯,比如業務模型以及數據訪問操作,

ASP.NET MVC 學習-- MVC中的資料夾

MVC 程式設計模型 MVC 是用於構建 web 應用程式的一種框架,使用 MVC (Model View Controller) 設計: Model(模型)表示應用程式核心(比如資料庫記錄列表) View(檢視)對資料(資料庫記錄)進行顯示 Controller(控

ASP.NET MVC 企業級實戰 —— 建立使用者許可權管理示例程式

網上有很多討論ASP.NET MVC,也有討論Jquery外掛的,同時把兩者結合起來做專案開發的卻是比較少。 ASP.NET MVC是比較優秀的後臺框架,而前臺採用JQuery外掛會做出比較漂亮美觀的介面。 講解了如何將兩者結合來開發Web應該系統。 將要建立的使用

【第一ASP.NET MVC快速入門之數據庫操作MVC5+EF6

c項目 教程 建數據庫 因此 F5 ctr 文件頭部 lec 跨站請求偽造 目錄 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入門之安全

Asp.Net MVC+EF+三層架構】詳解MVC VS 三層架構

前言:        接著上篇部落格說:MVC和三層架構到底是怎麼樣的一個關係?相同?或是迥異?或是部分相同,部分不同?或是思想同,邏輯不同?這是個值得思考的問題。關於三層架構大家應該差不多都有些瞭解

Asp.NET MVC 使用 SignalR 實現推送功能二Hubs 線上聊天室 獲取儲存使用者資訊

簡單介紹 在上一篇中,我們只是介紹了簡單的訊息推送,今天我們來修改一下,實現儲存訊息,歷史訊息和使用者線上 使用者登入註冊資訊 當用戶登入之後,我們註冊一下使用者的資訊,我們在ChatHub中 新建一個方法 Register(使用者帳號,使用者密碼) 前臺js呼叫這個方法實現使用者註冊 

Asp.NET MVC 使用 SignalR 實現推送功能一Hubs 線上聊天室

簡介       ASP .NET SignalR 是一個ASP .NET 下的類庫,可以在ASP .NET 的Web專案中實現實時通訊。什麼是實時通訊的Web呢?就是讓客戶端(Web頁面)和伺服器端可以互相通知訊息及呼叫方法,當然這是實時操作的。 WebSockets是HTML5提供的新的API

Asp.Net MVC+EF+三層架構】詳解初見

前言: 這個專案是小編我進入公司開始全面重頭開始著手的第一個專案,在寶寶的IT生涯裡這是一個里程碑,有著與眾不同的意義。那麼在之後小編會從頭至尾的寫一組關於Asp.Net MVC+EF+三層架構框架

ASP.NET MVC 學習筆記-3.Razor語法

OS 及其 wid resources 日期 ext str oca 區分   Razor語法是一種嵌入在網頁中基於服務器的代碼的編程語法。使用Razor語法的網頁中包括兩個不同類型的內容:客戶端內容和服務器內容。客戶端內容是網頁中常用的內容,比如,HTML標記(元素)、C

ASP.NET MVC 學習筆記-2.Razor語法

包含 鏈接 完整 rdquo 復雜 per 幫助 完成後 ade 1. 表達式 表達式必須跟在“@”符號之後, 2. 代碼塊 代碼塊必須位於“@{}”中,並且每行代碼必須以“;

ASP.NET MVC 學習: 檢視

用檢視呈現UI 檢視可以不包含任何應用邏輯或者資料庫檢索程式碼,所有的應用邏輯都可以在controller中進行處理。 檢視通過使用controller類在呼叫RenderView方法的時候提供檢視相關資料物件呈現UI: publicvoid Categories() {     List<C

ASP.NET MVC 學習筆記(一)

很久很久沒有在部落格園寫過東西了,很多大蝦也說過展示自己最好的地方就是有一個部落格作為筆記,展示一下自己的學習和研究成果。 最近決心將公司的一款產品改用MVC的方式實現,於是乎就開始在園子裡面瘋狂的尋找各種基於MVC的框架和EF的案例。終於找到一款基於MVC+EF+Bootstrap的框架,並且決定自己動手

ASP.NET MVC 學習 --- 第六課(根據使用者名稱登入網頁) log on log off

 public ActionResult LogOn(LogOnModel model, string returnUrl)         {             try             { //ManageService 中定義了驗證使用者名稱的方法 Ver

ASP.NET MVC 學習 --- HTML5 新特性及標籤

HTML 5 通過制定如何處理所有 HTML 元素以及如何從錯誤中恢復的精確規則,HTML 5 改進了互操作性,並減少了開發成本。 HTML 5 中的新特性包括了嵌入音訊、視訊和圖形的功能,客戶端資料儲存,以及互動式文件。 HTML 5 還包含了新的元素,比如:<na

ASP.NET MVC 學習(一) ado.net 呼叫儲存過程

ASP.NET MVC  學習(一) ado.net 呼叫儲存過程     見證我的菜鳥歷史: 想學一學儲存過程,自己寫了一下簡單的例子,發現了一些問題這裡記錄一下 以下是儲存過程: create

ASP.NET MVC 學習 --- 第七課(在非正常關閉IE之後,自動清除資料庫中的登陸資訊)

使用者Logon之後,我們可以在logoff裡面寫一些方法幫助我們清理資料庫中的一些資料。 但是如果使用者是非正常Logoff,而是直接關閉IE,如何去自動的清理資料庫中的資料吶。這裡是用session_end方法  方法一: 在Web.Config裡面 <sessi

Spring.NET教程整合NHibernate和ASP.NET MVC(基礎)

contains sar occurs false port company param soft stat 今天帶給大家的就是期待以久的ASP.net MVC與Spring.NET和NHibernate的組合,視圖打造.NET版的SSH(Spring-Struts-Hib