• MVC过滤器之添加LoginAttribute,浏览器提示:重定向次数太多


          以前在写登录Action过滤时,都在每个Controller前写上CheckLoginAttribute;这次决定偷懒试一下能否将所有Action和Controller统一过滤;

         开始代码是这样式儿的:

    1.新建一个特性类,继承ActionFilterAttribute,在Action执行前判断是否有登录记录Session,则在OnActionExecuting(ActionExecutingContext filterContext)中判断未登录,则返回登录界面;

     1  public class LoginAttribute:ActionFilterAttribute
     2     {
     3 
     4         public override void OnActionExecuting(ActionExecutingContext filterContext)
     5         {
     6             base.OnActionExecuting(filterContext);
     7             
     8             if (filterContext.HttpContext.Session["useruid"] == null)
     9             {
    10                 filterContext.Result = new RedirectResult("/Home/Login");
    11                 return;
    12             }
    13             
    14         }
    15     }

    2.在App_Start文件夹里的FilterConfig.cs,添加LoginAttribute

    1 public class FilterConfig
    2     {
    3         public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    4         {
    5             filters.Add(new HandleErrorAttribute());
    6             filters.Add(new LoginAttribute());//新增登录特性
    7         }
    8     }

    运行后,网页如下图,清除cookie完全无效。

    查找问题原因:单步调试后,发现RegisterGlobalFilters中的filters.Add(new LoginAttribute())  和 LoginAttribute中的RedirectResult,都会执行多次,次数和什么有关呢?

      在运行到LoginAttribute前,曾经在定义Controller的依赖注入UnityContainer里晃了一圈,重复执行RedirectResult的次数和容器注入的类数有关,先执行到依赖注入再执行到OnActionExecuting,应该是在Action操作之前,先对所有Controller依赖构造器接口进行初始化操作,初始化操作涉及到各个Controller。

      再看RegisterGlobalFilters初始化是属于Global.asax.cs,用于对全局文件配置的,在每执行一次Controller中的Action,都会执行一次LoginAttribute。于是初始化所有Controller依赖注入接口期间,有触发LoginAttribute。RouteConfig配置HomeLogin为默认启动Action。所以,在启动HomeLogin后,在初始化Controller的依赖注入后会连续多次执行RedirectResult(“/Home/Login“”),导致程序并没报错,而浏览器崩溃。

    于是这样改了试试:

     1  public override void OnActionExecuting(ActionExecutingContext filterContext)
     2         {
     3             base.OnActionExecuting(filterContext);
     4 
     5             //增加对初始化/Home/Login判定,直接跳出,避免多次执行RedirectResult
     6             string url = filterContext.HttpContext.Request.Url.ToString();
     7             if (url.IndexOf("Home") > 0&&url.IndexOf("Login")>0)
     8             {
     9                 return;
    10             }
    11             //增加部分到此结束
    12 
    13             if (filterContext.HttpContext.Session["useruid"] == null)
    14             {
    15                 filterContext.Result = new RedirectResult("/Home/Login");
    16                 return;
    17             }
    18         }

    然后暂时解决了。在各位大神帮忙指正下,添加标签的方式然后根据标签判断,比判断关键字符串,更便于扩展维护。

    最后代码如下:

     1 public class LoginAttribute:ActionFilterAttribute
     2     {
     3 
     4         public override void OnActionExecuting(ActionExecutingContext filterContext)
     5         {
     6              //判断Action描述标签中是否有AllowAnonymous特性
     7          if(filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true))
     8             {
     9                 return;
    10             }
    11 
    12             if (filterContext.HttpContext.Session["useruid"] == null)
    13             {
    14                 filterContext.Result = new RedirectResult("/Home/Login");
    15                 return;
    16             }
    17             base.OnActionExecuting(filterContext);
    18 
    19         }
    20     }
  • 相关阅读:
    协议分析 - DHCP协议解码详解
    在SqlServer2000的视图中小心使用*符号
    sql 将 varchar 值转换为数据类型为 int 的列时发生语法错误 的解决办法
    LECCO SQL Expert工具之优化sql语句
    css+js简单应用
    对任何一天是星期几算法的实现
    asp.net ajax 1.0 出现"sys"未定义解决方法
    js日历脚本
    在ASP.NET中重写URL
    在ASP.NET中重写URL (续篇)
  • 原文地址:https://www.cnblogs.com/blue-sandglass-2020/p/7090960.html
Copyright © 2020-2023  润新知