zoukankan      html  css  js  c++  java
  • 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添加特性,表示是否需要登录验证。

  • 相关阅读:
    【第40套模拟题】【noip2011_mayan】解题报告【map】【数论】【dfs】
    【模拟题(63550802...)】解题报告【贪心】【拓扑排序】【找规律】【树相关】
    【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】
    IMemoryBufferReference and IMemoryBufferByteAccess
    SoftwareBitmap and BitmapEncoder in Windows.Graphics.Imaging Namespace
    Windows UPnP APIs
    编译Android技术总结
    Windows函数转发器
    Two Ways in Delphi to Get IP Address on Android
    Delphi Call getifaddrs and freeifaddrs on Android
  • 原文地址:https://www.cnblogs.com/qk2014/p/4804631.html
Copyright © 2011-2022 走看看