在本文开始前,先简单讲两个知识点:

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() > )
{
var conAttr = controllerAttrs[] 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() > )
{
var attr = actionAttrs[] 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添加特性,表示是否需要登录验证。

C# mvc中为Controller或Action添加定制特性实现登录验证的更多相关文章

  1. asp.net Core 2.0 MVC为Controller或Action添加定制特性实现登录验证

    前言:最近在倒腾 微软的新平台 asp.net Core 2.0,在这个过程中有些东西还是存在差异.下面是我在学习过程的一点笔记.有不妥之处,望各位大虾指正! 一.先创建一个控制器继承于Control ...

  2. SSM框架中,controller的action返回参数给vue.js

    在SSM框架中,controller的action中,返回的是视图,即jsp页面或是ModelAndView,若是通过axios给vue传值的话,需要转换为字符串或是user实体类对象. 使用@Res ...

  3. [转]ASP.NET MVC中的两个Action之间值的传递--TempData

    本文转自:ASP.NET MVC中的两个Action之间值的传递--TempData 一. ASP.NET MVC中的TempData 在ASP.NET MVC框架的ControllerBase中存在 ...

  4. MVC中从Controller像View层传值

    MVC中的Controller不能直接的訪问View层中的控件,那么是怎样的将Controller中值传到View中,经常使用的有4种 ViewData: 是获取或设置视图的字典对象,它里面存放的是键 ...

  5. MVC中的Controller

    Controller是MVC模式中的三个核心元素之一. MVC模式中的Controller主要负责响应用户的输入, 并在响应时修改Model. MVC提供的是方法调用的结果, 而不是动态生成的页面. ...

  6. Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法

    Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx" ...

  7. 在ASP.NET非MVC环境中(WebForm中)构造MVC的URL参数,以及如何根据URL解析出匹配到MVC路由的Controller和Action

    目前项目中有个需求,需要在WebForm中去构造MVC的URL信息,这里写了一个帮助类可以在ASP.NET非MVC环境中(WebForm中)构造MVC的URL信息,主要就是借助当前Http上下文去构造 ...

  8. ASP.NET Core MVC 中的 [Controller] 和 [NonController]

    前言 我们知道,在 MVC 应用程序中,有一部分约定的内容.其中关于 Controller 的约定是这样的. 每个 Controller 类的名字以 Controller 结尾,并且放置在 Contr ...

  9. ASP.NET MVC中的两个Action之间值的传递--TempData

    一. ASP.NET MVC中的TempData 在ASP.NET MVC框架的ControllerBase中存在一个叫做TempData的Property,它的类型为TempDataDictiona ...

随机推荐

  1. bzoj1008 [HNOI2008]越狱

    1008: [HNOI2008]越狱 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5099  Solved: 2207 Description 监狱有 ...

  2. Boom.TV完成350万美元融资,目标直指VR电竞直播

    3D在线电竞直播平台Boom.tv刚刚宣布已经完成350万美元的融资,该平台旨在让观众在任何设备以任意视角观看电竞比赛,并将支持VR版本. 这家位于美国加州红木城的初创公司成立于2015年,由Gupt ...

  3. Code[VS] 1022 覆盖 题解

    Code[VS] 1022 覆盖 题解  Hungary Algorithm 题目传送门:Code[VS] 1022 题目描述 Description 有一个N×M的单位方格中,其中有些方格是水塘,其 ...

  4. 【BZOJ2821】作诗(Poetize) 分块

    Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次, ...

  5. VS开发好用的扩展

    VS开发好用的扩展(转) 转自:http://www.haogongju.net/art/1977373 首先为大家介绍一下开发字体,做程序开发,代码可读性,在侧面也能帮助开发提高效率,所以给大家介绍 ...

  6. ECLIPSE下SVN的创建分支/合并/切换使用

    最近接项目要求,要在svn主干上创建分支,用分支来进行程序的bug修改,而主干上进行新功能的开发.分支上的bug修改完,发布后,可以合并到主干上.项目程序可以在主干和分支之间进行切换,来实现主干和分支 ...

  7. HTML5标签简化写法

    基本页面格式 <!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title ...

  8. bzoj4562: [Haoi2016]食物链--记忆化搜索

    这道题其实比较水,半个小时AC= =对于我这样的渣渣来说真是极大的鼓舞 题目大意:给出一个有向图,求入度为0的点到出度为0的点一共有多少条路 从入读为零的点进行记忆化搜索,搜到出度为零的点返回1 所有 ...

  9. IntelliJ 有的时候移动滚动条后会自动回到光标所在位置的解决方法

    关闭有道词典的取词.划词功能.

  10. Cookie工具类

    import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet ...