zoukankan      html  css  js  c++  java
  • 在MVC里面使用Response.Redirect方法后记得返回EmptyResult

    在ASP.NET MVC中我们很多时候都会在拦截器和Controller中直接使用Response.Redirect方法做跳转,但是实际上Response.Redirect方法执行后ASP.NET并不会立即结束当前请求的执行,而是要过一段时间才会终止当前请求的执行,然后命令客户端浏览器去访问Response.Redirect方法中传入的新的URL地址。这会导致一个问题,有时候我们希望Response.Redirect方法执行后后面的代码就取消执行了,因为这并不是我们预期的行为,当代码执行了Response.Redirect方法后,如果其后面的部分代码还继续在执行甚至有可能报错。

    比如在下面的代码中我们演示了在MVC的IAuthorizationFilter拦截器中,如果用户没有登录应该立刻停止当前页面的请求,然后跳转到登录页面。我们使用了Response.Redirect方法来做跳转。

    复制代码
     1 public class AuthenticationFilterAttribute:ActionFilterAttribute,IAuthorizationFilter,IActionFilter
     2     {
     3         #region IAuthorizationFilter Members
     4 
     5         public void OnAuthorization(AuthorizationContext filterContext)
     6         {
     7 
     8             string curActionName = filterContext.ActionDescriptor.ActionName;
     9             string curControllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    10 
    11             if (!filterContext.HttpContext.Request.IsAuthenticated && (curControllerName.ToLower() != "login" || curActionName.ToLower() != "index"))
    12             {
    13                 filterContext.HttpContext.Response.Redirect(LoginHelper.LoginPageUrl, true);
    14                 return;
    15             }
    16         }
    17 
    18         #endregion
    19     }
    复制代码

    结果我惊讶的发现即便代码在上面13行Response.Redirect了,ASP.NET还是执行了当前请求URL对应Controller的Action中的代码,甚至执行了Action返回的View的Razor引擎代码。。。虽然最终这个view的内容没有呈现给客户端浏览器,浏览器最后还是正确跳转到了登录页。但是根据调试我们发现即便是我们执行了Response.Redirect方法,ASP.NET之后还是执行了一大堆本不该执行的代码

    所以这个时候我们需要用到EmptyResult这个对象,我们将上面的代码改成如下所示:

    复制代码
     1 public class AuthenticationFilterAttribute:ActionFilterAttribute,IAuthorizationFilter,IActionFilter
     2     {
     3         #region IAuthorizationFilter Members
     4 
     5         public void OnAuthorization(AuthorizationContext filterContext)
     6         {
     7 
     8             string curActionName = filterContext.ActionDescriptor.ActionName;
     9             string curControllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    10 
    11             if (!filterContext.HttpContext.Request.IsAuthenticated && (curControllerName.ToLower() != "login" || curActionName.ToLower() != "index"))
    12             {
    13                 filterContext.HttpContext.Response.Redirect(LoginHelper.LoginPageUrl, true);
    14                 filterContext.Result = new EmptyResult();//加入EmptyResult就告诉ASP.NET MVC在本拦截器执行结束后,不必再为当前请求执行Controller中Action的代码
    15                 return;
    16             }
    17         }
    18 
    19         #endregion
    20     }
    复制代码

    那么ASP.NET MVC在执行完上面的IAuthorizationFilter拦截器后,就会发现EmptyResult被赋值在了参数filterContext的Result属性上,就会终止执行Controller的Action,立即结束当前请求的执行,不会再去执行多余的代码了。

    所以很多时候我们在ASP.NET中使用Response.Redirect方法时要相当小心,一定要知道Response.Redirect方法执行后并不等于代码就结束执行了,还要考虑到后面的代码一旦被误执行会有什么后果,有什么办法可以避免。在MVC中使用EmptyResult就是个不错的选择。

  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/Alex80/p/6421874.html
Copyright © 2011-2022 走看看