MVC過濾器之添加LoginAttribute,瀏覽器提示:重定向次數太多


      以前在寫登錄Action過濾時,都在每個Controller前寫上CheckLoginAttribute;這次決定偷懶試一下能否將所有Action和Controller統一過濾;

     開始代碼是這樣式兒的:

1.新建一個特性類,繼承ActionFilterAttribute,在Action執行前判斷是否有登錄記錄Session,則在OnActionExecuting(ActionExecutingContext filterContext)中判斷未登錄,則返回登錄界面;

 1  public class LoginAttribute:ActionFilterAttribute
 2     {
 3 
 4         public override void OnActionExecuting(ActionExecutingContext filterContext)
 5         {
 6             base.OnActionExecuting(filterContext);
 7             
 8             if (filterContext.HttpContext.Session["useruid"] == null)
 9             {
10                 filterContext.Result = new RedirectResult("/Home/Login");
11                 return;
12             }
13             
14         }
15     }

2.在App_Start文件夾里的FilterConfig.cs,添加LoginAttribute

1 public class FilterConfig
2     {
3         public static void RegisterGlobalFilters(GlobalFilterCollection filters)
4         {
5             filters.Add(new HandleErrorAttribute());
6             filters.Add(new LoginAttribute());//新增登錄特性
7         }
8     }

運行后,網頁如下圖,清除cookie完全無效。

查找問題原因:單步調試后,發現RegisterGlobalFilters中的filters.Add(new LoginAttribute())  和 LoginAttribute中的RedirectResult,都會執行多次,次數和什么有關呢?

  在運行到LoginAttribute前,曾經在定義Controller的依賴注入UnityContainer里晃了一圈,重復執行RedirectResult的次數和容器注入的類數有關,先執行到依賴注入再執行到OnActionExecuting,應該是在Action操作之前,先對所有Controller依賴構造器接口進行初始化操作,初始化操作涉及到各個Controller。

  再看RegisterGlobalFilters初始化是屬於Global.asax.cs,用於對全局文件配置的,在每執行一次Controller中的Action,都會執行一次LoginAttribute。於是初始化所有Controller依賴注入接口期間,有觸發LoginAttribute。RouteConfig配置Home\Login為默認啟動Action。所以,在啟動Home\Login后,在初始化Controller的依賴注入后會連續多次執行RedirectResult(“/Home/Login“”),導致程序並沒報錯,而瀏覽器崩潰。

於是這樣改了試試:

 1  public override void OnActionExecuting(ActionExecutingContext filterContext)
 2         {
 3             base.OnActionExecuting(filterContext);
 4 
 5             //增加對初始化/Home/Login判定,直接跳出,避免多次執行RedirectResult
 6             string url = filterContext.HttpContext.Request.Url.ToString();
 7             if (url.IndexOf("Home") > 0&&url.IndexOf("Login")>0)
 8             {
 9                 return;
10             }
11             //增加部分到此結束
12 
13             if (filterContext.HttpContext.Session["useruid"] == null)
14             {
15                 filterContext.Result = new RedirectResult("/Home/Login");
16                 return;
17             }
18         }

然后暫時解決了。在各位大神幫忙指正下,添加標簽的方式然后根據標簽判斷,比判斷關鍵字符串,更便於擴展維護。

最后代碼如下:

 1 public class LoginAttribute:ActionFilterAttribute
 2     {
 3 
 4         public override void OnActionExecuting(ActionExecutingContext filterContext)
 5         {
 6              //判斷Action描述標簽中是否有AllowAnonymous特性
 7          if(filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true))
 8             {
 9                 return;
10             }
11 
12             if (filterContext.HttpContext.Session["useruid"] == null)
13             {
14                 filterContext.Result = new RedirectResult("/Home/Login");
15                 return;
16             }
17             base.OnActionExecuting(filterContext);
18 
19         }
20     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM