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

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. BZOJ3189 : [Coci2011]Slika

    通过离线将操作建树,即可得到最终存在的操作. 然后逆着操作的顺序,倒着进行染色,对于每行维护一个并查集即可. 时间复杂度$O(n(n+m))$. #include<cstdio> cons ...

  2. Android的Proxy/Delegate Application框架 (主要介绍插件化开发)

    1. 插件化的原理 是 Java ClassLoader 的原理:Java ClassLoader基础 常用的其他解决方法还包括:Google Multidex,用 H5 代替部分逻辑,删无用代码,买 ...

  3. iOS模拟器多个虚拟机怎么处理

    1:关闭Xcode和模拟器 2:$sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService 等待输入密码 3:$rm -f ~/Libr ...

  4. petapoco定制,比较SQL事务,存储过程,分布式事务(MSDTC)的区别和场景

    使用分布式事务时 就锁死了,而且是只锁编辑的行 使用.netSQL事务一定要执行了一个CUD的SQL才会锁死,而且也是锁行,但是也锁读的行 .netSQL事务要在这里才锁死 结论,对于产品要求细粒度的 ...

  5. css圆角边框

    一.CSS3圆角的优点 传统的圆角生成方案,必须使用多张图片作为背景图案.CSS3的出现,使得我们再也不必浪费时间去制作这些图片了,而且还有其他多个优点: * 减少维护的工作量.图片文件的生成.更新. ...

  6. 第 2 章 让jsp说hello

    2.1. 另一个简单jsp 上一篇举的例子很单纯,无论谁向服务器发送请求,服务器都只计算当前系统时间,然后把这个时间制作成http响应发还给浏览器. 可惜这种单向的响应没办法实现复杂的业务,比如像这样 ...

  7. javascript平时小例子⑤(投票效果的练习)

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  8. 实验验证redis的快照和AOF

    安装配置redis http://www.cnblogs.com/myrunning/p/4222385.html 验证redis的主从复制 http://www.cnblogs.com/myrunn ...

  9. 无法分配超出32(XXX)的MINEXTENTS报错的解决方法

    今天在创建新表的时候,遇到该报错:ORA-01659 无法分配超出32(XXX)的MINEXTENTS 解决方法:修改表空间大小. 命令如下: ALTER DATABASE DATAFILE ''D: ...

  10. 自动删除Mysql备份(数组+for)

    #!/bin/bash #author:V #Dispaly:auto delete mysql backup. BACKDIR=(/home/11/mysqlbackup/ /home/full/) ...