C# mvc中為Controller或Action添加定制特性實現登錄驗證


在本文開始前,先簡單講兩個知識點:

1.每個action執行前都會先執行OnActionExecuting方法;

2.FCL提供了多種方式來檢測特性的存在,比如IsDefined、GetCustomAttributes方法等,IsDefined方法僅僅是判斷目標有沒有應用指定特性,而GetCustomAttributes方法會構造指定特性的新實例。

一、下面先利用OnActionExecuting和IsDefined這兩個方法實現判斷action是否需要登錄

1.新建mvc項目,實現定制特性CheckLogin,如下:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false)]
    public sealed class CheckLogin : Attribute
    {
        //什么都無需寫
    }

2.新建控制器,命名“ParentController”(以后新建的控制器都繼承它),重寫OnActionExecuting方法,如下:

public class ParentController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            
//判斷action是否有CheckLogin特性 bool isNeedLogin = filterContext.ActionDescriptor.IsDefined(typeof(CheckLogin), false); if (isNeedLogin) { if (!IsLogin()) { //如果沒有登錄,則跳至登陸頁 filterContext.Result = Redirect("/User/Login"); } } } protected bool IsLogin() { if (Session["UserInfo"] != null) return true; return false; } }

 

3.新建控制器“HomeController”,繼承“ParentController”,如下

public class HomeController : ParentController
 {        public ActionResult Index()
        {
            return View();
        }        
    [CheckLogin] 
    public ActionResult About()
    {
      
return View();
    }
}

在“HomeController”內,執行Index方法無需登錄驗證,執行About方法前需要登錄驗證。簡單的判斷action登錄驗證的功能就ok了。

思考:

對於上面的功能,如果特性CheckLogin應用在控制器(Controller)上,那么該控制器內的所有action都需登錄驗證(當然OnActionExecuting方法內需加判斷控制器是否有特性的代碼),這樣不必為每個action加[CheckLogin]了。

但是,這里會有一個問題:如果控制器加了特性CheckLogin,並且該控制器下有100個action,只有一個或幾個action無需登錄登錄驗證,那么上面的功能就顯得不夠靈活了。

解決方法是,為特性CheckLogin加一個屬性,來表明是否需要登錄驗證,

二、下面利用OnActionExecuting和GetCustomAttributes這兩個方法實現判斷action是否需要登錄

1.修改定制特性CheckLogin,如下:

public sealed class CheckLogin : Attribute
    {
        public bool IsNeedLogin = false;

        public CheckLogin (bool isNeed)
        {
            this.IsNeedLogin = isNeed;
        }
    }

IsNeedLogin=true表示需要登錄驗證,IsNeedLogin=false無需。

 

2.修改ParentController控制器,如下:

public class BaseController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);

            bool result = false;

            //controller上是否有特性CheckLogin,以及特性的IsNeedLogin值
            var controllerAttrs = filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(CheckLogin), false);
            if (controllerAttrs.Count() > 0)
            {
                var conAttr = controllerAttrs[0] as CheckLogin;
                if (conAttr != null)
                {
                    if (conAttr.IsNeedLogin)
                        result = true;
                    else
                        result = false;
                }
            }

            //action上是否有特性CheckLogin,以及特性的IsNeedLogin值
            var actionAttrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(CheckLogin), false);
            if (actionAttrs.Count() > 0)
            {
                var attr = actionAttrs[0] as CheckLogin;
                if (attr != null)
                {
                    if (attr.IsNeedLogin)
                        result = true;
                    else
                        result = false;                    
                }
            }

            if (!IsLogin() && result)
            {
                //如果沒有登錄,則跳至登陸頁
                filterContext.Result = Redirect("/User/Login");
            }
        }

        protected bool IsLogin()
        {
            if (Session["UserInfo"] != null)
                return true;

            return false;
        }
    }

3.修改HomeController,如下:

[CheckLogin(true)]
    public class HomeController : ParentController
    {
        [CheckLogin(false)]
        public ActionResult Index()
        {
            return View();
        }

        
        public ActionResult About()
        {
            return View();
        }
    }

 

代碼寫到這,就可以更靈活為controller或action添加特性,表示是否需要登錄驗證。

 


免責聲明!

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



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