当我使用Response.Redirect(…)将我的表单重定向到一个新页面时,我得到了错误:
类型为'System.Threading '的第一次机会异常。mscorlib.dll中出现ThreadAbortException `
System.Threading类型的异常。在mscorlib.dll中出现ThreadAbortException',但在用户代码中没有处理
我对此的理解是,该错误是由web服务器中止余下的页面响应引起的。重定向被调用。
I know I can add a second parameter to Response.Redirect that is called endResponse. If I set endResponse to True I still get the error but if I set it to False then I do not. I am pretty sure though that that means the webserver is running the rest of the page I redirected away from. Which would seem to be inefficient to say the least. Is there a better way to do this? Something other than Response.Redirect or is there a way to force the old page to stop loading where I will not get a ThreadAbortException?
redirect()抛出异常终止当前请求。
这篇KB文章描述了这种行为(也适用于Request.End()和Server.Transfer()方法)。
对于Response.Redirect()存在重载:
Response.Redirect(String url, bool endResponse)
如果传递endResponse=false,则不会抛出异常(但运行时将继续处理当前请求)。
如果endResponse=true(或者使用了其他重载),则抛出异常,当前请求将立即终止。
redirect()抛出异常终止当前请求。
这篇KB文章描述了这种行为(也适用于Request.End()和Server.Transfer()方法)。
对于Response.Redirect()存在重载:
Response.Redirect(String url, bool endResponse)
如果传递endResponse=false,则不会抛出异常(但运行时将继续处理当前请求)。
如果endResponse=true(或者使用了其他重载),则抛出异常,当前请求将立即终止。
对于ASP中的重定向问题,没有简单而优雅的解决方案。净WebForms。您可以在肮脏的解决方案和乏味的解决方案之间进行选择
Response.Redirect(url)发送一个重定向到浏览器,然后抛出一个ThreadAbortedException来终止当前线程。因此,在Redirect()调用之后不会执行任何代码。缺点:像这样杀死线程是一种糟糕的做法,会影响性能。此外,ThreadAbortedExceptions将显示在异常日志记录中。
Tedious: The recommended way is to call Response.Redirect(url, false) and then Context.ApplicationInstance.CompleteRequest() However, code execution will continue and the rest of the event handlers in the page lifecycle will still be executed. (E.g. if you perform the redirect in Page_Load, not only will the rest of the handler be executed, Page_PreRender and so on will also still be called - the rendered page will just not be sent to the browser. You can avoid the extra processing by e.g. setting a flag on the page, and then let subsequent event handlers check this flag before before doing any processing.
(CompleteRequest的文档声明它“导致ASP。NET可以绕过HTTP管道执行链中的所有事件和过滤”。这很容易被误解。它会绕过进一步的HTTP过滤器和模块,但不会绕过当前页面生命周期中的进一步事件。)
更深层次的问题是WebForms缺乏抽象级别。当您处于事件处理程序中时,您已经处于构建要输出的页面的过程中。在事件处理程序中重定向是丑陋的,因为您要终止部分生成的页面以生成不同的页面。MVC没有这个问题,因为控制流与呈现视图是分开的,所以你可以通过简单地在控制器中返回一个RedirectAction来做一个干净的重定向,而不生成视图。
我知道我迟到了,但我只有在响应时才会出现这种错误。重定向正在尝试中…Catch块。
永远不要放一个响应。重定向到尝试…Catch块。这是不好的做法
作为放置响应的替代方法。重定向到尝试…Catch块,我将把方法/函数分解为两个步骤。
在Try…Catch块执行请求的操作,并设置一个“结果”值来指示操作的成功或失败。
在Try…Catch块是否重定向取决于“结果”值是什么。
这段代码远非完美,可能不应该复制,因为我还没有测试过它。
public void btnLogin_Click(UserLoginViewModel model)
{
bool ValidLogin = false; // this is our "result value"
try
{
using (Context Db = new Context)
{
User User = new User();
if (String.IsNullOrEmpty(model.EmailAddress))
ValidLogin = false; // no email address was entered
else
User = Db.FirstOrDefault(x => x.EmailAddress == model.EmailAddress);
if (User != null && User.PasswordHash == Hashing.CreateHash(model.Password))
ValidLogin = true; // login succeeded
}
}
catch (Exception ex)
{
throw ex; // something went wrong so throw an error
}
if (ValidLogin)
{
GenerateCookie(User);
Response.Redirect("~/Members/Default.aspx");
}
else
{
// do something to indicate that the login failed.
}
}