C# 在不引发异常的情况下执行Response.Redirect()何时安全?
我有一个中间类扩展System.Web.UI.Page,用于所有需要身份验证的页面。该类主要执行自定义身份验证处理 当访问权限不足的用户尝试访问某个页面时,我会尝试将用户重定向回登录页面,同时防止执行任何进一步的页面事件(即页面加载)。想到的第一个解决方案是Response.Redirect的默认实现。当然,这样做的缺点是可能会抛出ThreadAbortException 所以我的问题是:在页面生命周期中,何时(如果有的话)在不抛出ThreadAbortException的情况下执行Response.Redirect()是安全的C# 在不引发异常的情况下执行Response.Redirect()何时安全?,c#,asp.net,response.redirect,C#,Asp.net,Response.redirect,我有一个中间类扩展System.Web.UI.Page,用于所有需要身份验证的页面。该类主要执行自定义身份验证处理 当访问权限不足的用户尝试访问某个页面时,我会尝试将用户重定向回登录页面,同时防止执行任何进一步的页面事件(即页面加载)。想到的第一个解决方案是Response.Redirect的默认实现。当然,这样做的缺点是可能会抛出ThreadAbortException 所以我的问题是:在页面生命周期中,何时(如果有的话)在不抛出ThreadAbortException的情况下执行Respon
public class CustomPage : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!IsValid())
Response.Redirect("login.aspx", true);
}
}
好奇的是,你自己为什么要这么做?如果有的话,您应该使用其中一个身份验证提供者(最终,FormsAuthentication可以定制为处理您所能想到的几乎任何场景) 然后,您可以使用web.config文件中的来指示匿名用户无法访问哪些页面/目录。ASP.NET将处理其余部分,将用户重定向到您指定的登录页面,并在用户登录后重定向回。如果将true作为第二个参数传递,则永远不会“安全”——它将始终引发异常。在内部,
Response.Redirect()
调用Response.End()
,直接中止当前线程
截断HttpRequest而不引发异常的唯一“安全”方法是使用,但这将导致在当前请求中进一步执行代码 如果不希望出现ThreadAbort异常,则应将False传递给endResponse参数。当然,这意味着您必须处理页面的其余部分,这很难做到正确 除非您正在做一些非常愚蠢的事情,比如持有锁,否则在ASP.NET页面中抛出ThreadAbort异常是完全安全的
另一个选项是使用Server.Transfer。这比重定向具有更好的性能,但它也使用ThreadAbort异常。为什么不希望抛出ThreadAbortException呢。抛出它是为了停止对请求页面的任何进一步处理。我想这是真的。但是,如果在VS中启用自动异常中断,Response.Redirect()并不总是抛出异常,但它仍然会跳过处理页面的其余部分。这是我考虑过的一个选项。我认为这是我提出的解决方案中最简单、最容易维护的。所有需要验证的页面都保存在一个目录中。有5个以上的角色用于访问页面,目录(20+)中的每个页面都有不同的角色要求。我看到自己在web.config中为每个需要身份验证的页面创建了一个位置部分。我的另一个选择是为每个角色将文件拆分为单独的目录。我遇到的问题是,如果一个用户扮演多个角色,路径维护。我不确定情况是否如此。我不这么认为的原因是Response.End()在抛出异常之前检查IsInCancellablePeriod。因此,不知何故,可以在某个地方调用Response.End(),而不会碰到异常。您需要深入挖掘。您将看到,IsInCancellablePeriod完全由HttpApplication.IExecutionStep接口对象上的标志控制。此标志定义为
return!(此._application.Context.Handler是IHTTPassynchandler)代码>用于任何CallHandler实现(调用ProcessRequest,调用页面生命周期)。换句话说,除非您正在执行异步请求,否则在整个页面生命周期中,它将始终为false。因此,如果我在没有try/catch的情况下调用Response.Redirect(“login.aspx”),它不应该出现HttpApplication.Application\u错误(事实并非如此)吗?我认为应该,尽管我可能是错的。ThreadAbortException是一个非常特殊的例外情况。