前言当我们访问某个网站的时候需要检测用户是否已经登录(通过Session是否为null),我们知道在WebForm中可以定义一个BasePage类让他继承System.Web.UI.Page,重写它的OnInit()方法,在OnInit()中判断Session中是否有用户登录的信息。

/// <summary>
/// 公共基类里面干一些公共的事情
/// </summary>
public class BasePage : System.Web.UI.Page
{
//页面生命周期Init事件对应的OnInit()方法
//这个方法会先于PageLoad方法执行
//override 表示重写 OnInit方法 OnInit 方法,在所有控件都已初始化且已应用所有外观设置后引发。使用该事件来读取或初始化控件属性
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Session["UserInfo"] == null) //检查用户是否登录
{
//跳转到登录页面
}
}
}

 在mvc下该怎样校验呢?

我们知道,MVC下可以自定义特性类为控制器或控制器中的Action打上[特性],这里只需要ActionFilter过滤器(Action方法执行前后执行),MVC提供了IActionFilter接口。(为了方便我们可以用微软提供好的ActionFilterAttribute类,他是筛选器特性的基类,也是一个抽象类,其实这个抽象类实现了IActionFilter和IResultFilter)

IActionFilter接口的定义:

   //在执行操作方法后调用。
void OnActionExecuted(ActionExecutedContext filterContext); // 在执行操作方法之前调用。
void OnActionExecuting(ActionExecutingContext filterContext);

新建一个特性类LoginCheckFilterAttribute,让他继承ActionFilterAttribute,并重写其中的OnActionExecuting方法,在其中完成校验

public class LoginCheckFilterAttribute : ActionFilterAttribute
{
//表示是否检查登录
public bool IsCheck { get; set; } //Action方法执行之前执行此方法
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext); if (IsCheck)
{
//校验用户是否已经登录
if (filterContext.HttpContext.Session["loginUser"] == null)
{
//跳转到登陆页
filterContext.HttpContext.Response.Redirect("/UserLogin/Index");
}
}
}
}

怎么让这个过滤器起作用呢?

步骤:1、在Global.asax文件中为MVC程序注册全局过滤器, 调用FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)。FilterConfig类在App_Start文件夹中(创建新的MVC项目会自动生成),在FilterConfig的静态方法中public static void RegisterGlobalFilters(GlobalFilterCollection filters)注册全局过滤器

public class FilterConfig
{
//这个方法是用于注册全局过滤器(在Global中被调用)
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
filters.Add(new LoginCheckFilterAttribute() { IsCheck = true });
}
}

注意要为特性类实例的IsCheck属性赋值true否则Session校验不起作用。

这样子,LoginCheckFilterAttribute这个特性就会对整个MVC程序中的控制器和Action起作用了,就是说在执行Action方法之前会先调用特性类中的重写OnActionExecuting方法,这样用户在访问网站的时候会首先检测用户是否已经登录,如果没有登录会跳转到登录页面。

但是!但是!问题来了,因为我们注册的是全局的过滤器,这个过滤特性会对所有的控制器下的Action起作用,当访问网站的时候会(比如我们注册默认路由为/Home/Index)会首先跳转到/Home/Index,这时不会执行Index方法,会先执行OnActionExecuting()中的校验,发现Session为null,Response.Redirect("/UserLogin/Index")跳转到了登录页面;这时我们在浏览器中依然看不到登录页面,为什么呢?还记得我们注册的全局的过滤器,作用对象包括所有控制器下的Action当然也包括/UserLogin/Index,代码走到了这里会再次执行OnActionExecuting()方法,发现Session["UserInfo"==]null,又跳到了登录页面,我们连登录页面都见不着肯定不能输入用户名密码Session也就不会有登录信息,浏览器会返回 ”此网页包含重定向循环“ 的错误页面,也就是说会一直循环不停的重定向到登录页面,类似死循环,浏览器当然罢工了。。

该怎样解决这个bug的?

解决方法:为UserLoginController控制器打上特性

[LoginCheckFilterAttribute(IsCheck = false)]  //打上用户登录校验特性(IsCheck设为false不让它对此控制器起作用,而对其他控制器和Action起作用,防止重定向循环)
public class UserLoginController : Controller
{     ... }

我们在定义这个特性类的时候 有个bool属性 IsCheck,它表示是否校验,这里设为false表示不校验。顺便说一下LoginCheckFilterAttribute可以省略Attrbute后缀。

一定要在控制器上打这个特性,不要只针对下边的某个Action,因为这里边有生成验证码的Action和处理登录请求的Action,它们都不需要进行session校验(没意义),在控制器上打上特性会对它下边的所有Action起作用,不用为每个Action打特性了,节省代码量。我们注册了全局过滤器,又单独为UserLoginController控制器打上过滤特性,这里有一个优先级的问题Action>Controller>全局,UserLoginController不会受全局过滤器的影响。到这里测试一下,输入网站地址,成功进入登录页面。问题解决。

本文主要参考了:http://www.cnblogs.com/Look_Sun/p/4425083.html这篇文章。我遇到这个问题的时候,看了这篇文章和我开发时候遇到的问题基本一样。但是那哥们写的全局过滤器好像有问题,只需要判断Session["userinfo"]==null的时候就可以,他把Session["userinfo"]!=null的时候也做了判断,并做了跳转到。所有当点击登陆的时候,重定向到了/Home/Index,但是到了Home又会是个死循环。

MVC中过滤器中非常好的一个视屏:http://pan.baidu.com/s/1i5zwhjZ   回复我要密码  以后共同探讨问题

MVC中使用Action全局过滤器出现:网页无法正常运作 将您重定向的次数过多。解决办法的更多相关文章

  1. iOS 全局禁止横屏,但UIWebView 全屏播放视频,横屏,解决办法(任意页面横竖屏或禁止)

    iOS 全局禁止横屏,但UIWebView 全屏播放视频,横屏,解决办法 时间 2015-07-14 20:59:00  博客园-原创精华区 原文  http://www.cnblogs.com/fe ...

  2. SecureCRT SSH Linux中不显示彩色 字体颜色、文件夹和文件显示的颜色区别开解决办法

    SecureCRT SSH Linux中不显示彩色 字体颜色.文件夹和文件显示的颜色区别开解决办法 实验环境: 刚开始我的情况是这样的:带颜色的显示不出来,然后还能看到,此处有内容,猜测是Secure ...

  3. MVC下用户登录状态校验的问题以及解决方案--------------Action全局过滤器的使用

    前言当我们访问某个网站的时候需要检测用户是否已经登录(通过Session是否为null),我们知道在WebForm中可以定义一个BasePage类让他继承System.Web.UI.Page,重写它的 ...

  4. (原创)spring mvc和jersey rest 组合使用时单例对像实例化两次的BUG及解决办法

    项目中没用spring 的restTemplate 而是采用 jersey来做rest 的实现,一直用着,也没发现有什么不对,后来加入了,以quartz用硬编码方式实现,结果启动项目的时候报错 ,具体 ...

  5. 【Azure Developer】Github Action部署资源(ARM模板)到Azure中国区时,遇见登录问题的解决办法

    问题描述 在参考文档"使用 GitHub Actions 部署 ARM 模板"一文中,由于是在中国区Azure上操作,所以生产的部署凭证为中国区凭证.当创建工作流时,在登录到Azu ...

  6. 在WIn32程序中使用MFC的CInternetSession运行异常,主要是因为获取目前应用程序名出错的解决办法

    转载:http://group.gimoo.net/review/22564 头文件#include <afxinet.h"> 在非MFC工程中使用CInternetSessio ...

  7. Android中 在显示ImageView时图片上面和下面都出现一段空白区间的解决办法

    开始的时候是在ScrollView中显示ImageView的时候出现这样的问题,以为是要对ScrollView进行设置的,后来发现单独显示一个ImageView的时候也会出现这样的问题,由此才知道是应 ...

  8. Python中编码问题:u'\xe6\x97\xa0\xe5\x90\x8d' 类型的转为utf-8的解决办法

    相信小伙伴们遇到过类似这样的问题,python2中各种头疼的转码,类似u'\xe6\x97\xa0\xe5\x90\x8d' 的编码,直接s.decode()是无法解决编码问题.尝试了无数办法,都无法 ...

  9. JEECG中出现Java.sql.SQLException: Value 'xxxx' can not be represented as java.sql.Timestamp的解决办法

    出现`Java.sql.SQLException: Value 'xxxx' can not be represented as java.sql.Timestamp',其中xxxx部分对应包含一个看 ...

随机推荐

  1. 软件工程(FZU2015)赛季得分榜,第10回合(alpha冲刺)

    目录 第一回合 第二回合 第三回合 第四回合 第五回合 第6回合 第7回合 第8回合 第9回合 第10回合 第11回合 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分 ...

  2. 创建django项目

    python /usr/local/lib/python3.4/dist-packages/Django-1.9.10-py3.4.egg/django/bin/django-admin.py sta ...

  3. 使用Maven Assembly plugin将依赖打包进jar

    一个Eclipse的工程,在pom中配置了若干依赖,需要将pom中所有的依赖全部打包进一个jar包中,可以选择的方案有maven-assembly-plugin和fatjar.以前采用fatjar进行 ...

  4. 《Python核心编程》18.多线程编程(二)

    18.1没有线程支持 #!/usr/bin/env python # -*- coding:utf-8 -*- from time import sleep, ctime def loop0(): p ...

  5. .Net 中的反射(序章) - Part.1

    引言 反射是.Net提供给我们的一件强力武器,尽管大多数情况下我们不常用到反射,尽管我们可能也不需要精通它,但对反射的使用作以初步了解在日后的开发中或许会有所帮助. 反射是一个庞大的话题,牵扯到的知识 ...

  6. CSS 和 JS 动画哪个更快

    基于Javascript的动画暗中同CSS过渡效果一样,甚至更加快,这怎么可能呢?而Adobe和Google持续发布的富媒体移动网站的性能可媲美本地应用,这又怎么可能呢? 本文逐一遍览了基于Javas ...

  7. C#学习笔记

    1.C#中[],List,Array,ArrayList的区别 [] 是针对特定类型.固定长度的. List 是针对特定类型.任意长度的. Array 是针对任意类型.固定长度的. ArrayList ...

  8. linux 根据文件大小查找文件

    inux下的find命令用来查找文件,通过man find就知道它是无所不能的.所以按照文件大小来查找文件就不在话下.从man find搜索size,可以看到如下信息: -size n[cwbkMG] ...

  9. Android-修改TabWidget字体大小颜色及对齐

    在Android中,我们可以定义TabWidget来分页.在上一篇文章中有说到使用TabWidget定义Tab分页布局,但大部分用户可能会觉得默认的字体有点小,但Tab选项卡默认又不能设定字体大小,如 ...

  10. HDOJ 4652 Dice

      期望DP +数学推导 Dice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...