Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在不引发异常的情况下执行Response.Redirect()何时安全?_C#_Asp.net_Response.redirect - Fatal编程技术网

C# 在不引发异常的情况下执行Response.Redirect()何时安全?

C# 在不引发异常的情况下执行Response.Redirect()何时安全?,c#,asp.net,response.redirect,C#,Asp.net,Response.redirect,我有一个中间类扩展System.Web.UI.Page,用于所有需要身份验证的页面。该类主要执行自定义身份验证处理 当访问权限不足的用户尝试访问某个页面时,我会尝试将用户重定向回登录页面,同时防止执行任何进一步的页面事件(即页面加载)。想到的第一个解决方案是Response.Redirect的默认实现。当然,这样做的缺点是可能会抛出ThreadAbortException 所以我的问题是:在页面生命周期中,何时(如果有的话)在不抛出ThreadAbortException的情况下执行Respon

我有一个中间类扩展System.Web.UI.Page,用于所有需要身份验证的页面。该类主要执行自定义身份验证处理

当访问权限不足的用户尝试访问某个页面时,我会尝试将用户重定向回登录页面,同时防止执行任何进一步的页面事件(即页面加载)。想到的第一个解决方案是Response.Redirect的默认实现。当然,这样做的缺点是可能会抛出ThreadAbortException

所以我的问题是:在页面生命周期中,何时(如果有的话)在不抛出ThreadAbortException的情况下执行Response.Redirect()是安全的

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是一个非常特殊的例外情况。