Ben*_*man 227 c# asp.net .net-3.5
当我使用Response.Redirect(...)将表单重定向到新页面时,我收到错误:
mscorlib.dll中出现"System.Threading.ThreadAbortException"类型的第一次机会异常mscorlib.dll中
出现"System.Threading.ThreadAbortException"类型的异常,但未在用户代码中处理
我对此的理解是,错误是由Web服务器中止调用response.redirect的页面的其余部分引起的.
我知道我可以添加第二个参数Response.Redirect,称为endResponse.如果我将endResponse设置为True,我仍然会收到错误,但如果我将其设置为False,那么我不会.我很确定,这意味着网络服务器正在运行我重定向的页面的其余部分.至少可以说这似乎效率低下.有一个更好的方法吗?除了Response.Redirect或有没有办法迫使旧页面停止加载我不会得到的东西ThreadAbortException?
Joe*_*ore 329
正确的模式是使用endResponse = false调用Redirect重载并调用告诉IIS管道,一旦返回控件,它应该直接前进到EndRequest阶段:
Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();
Run Code Online (Sandbox Code Playgroud)
Thomas Marquardt的这篇博客文章提供了其他详细信息,包括如何处理Application_Error处理程序内部重定向的特殊情况.
Jac*_*esB 154
有没有简单而优雅的解决Redirect在ASP.Net WebForms的问题.您可以选择Dirty解决方案和Tedious解决方案
脏:Response.Redirect(url)向浏览器发送重定向,然后抛出一个ThreadAbortedException终止当前线程.因此,没有代码执行Redirect() - 调用.缺点:这是一种不好的做法,并且会对杀死这样的线程产生影响.此外,ThreadAbortedExceptions将显示异常日志记录.
乏味:推荐的方法是调用Response.Redirect(url, false)然后Context.ApplicationInstance.CompleteRequest(),代码执行将继续,页面生命周期中的其余事件处理程序仍将执行.(例如,如果您在Page_Load中执行重定向,则不仅会执行处理程序的其余部分,还会调用Page_PreRender等等 - 渲染的页面将不会被发送到浏览器.您可以避免额外的处理例如,在页面上设置一个标志,然后让后续事件处理程序在进行任何处理之前检查此标志.
(文档CompleteRequest声明它" 导致ASP.NET绕过所有事件并在HTTP管道执行链中进行过滤 ".这很容易被误解.它确实绕过了更多的HTTP过滤器和模块,但它没有绕过更多的事件在当前页面生命周期中.)
更深层次的问题是WebForms缺乏抽象层次.当您在事件处理程序中时,您已经在构建要输出的页面的过程中.在事件处理程序中重定向很难看,因为您要终止部分生成的页面以生成不同的页面.MVC没有这个问题,因为控制流与渲染视图是分开的,所以你可以通过RedirectAction在控制器中返回a 而不生成视图来进行干净的重定向.
Ort*_*und 31
我知道我已经迟到了,但如果我Response.Redirect在一个Try...Catch街区,我只会遇到这个错误.
永远不要将Response.Redirect放入Try ... Catch块.这是不好的做法
为了回应@Kiquenet的评论,我将做的是将Response.Redirect放入Try ... 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.
}
}
Run Code Online (Sandbox Code Playgroud)
Response.Redirect() 抛出异常以中止当前请求.
此知识库文章描述了此行为(也适用于Request.End()和Server.Transfer()方法).
因为Response.Redirect()存在过载:
Response.Redirect(String url, bool endResponse)
Run Code Online (Sandbox Code Playgroud)
如果传递endResponse = false,则不会抛出异常(但运行时将继续处理当前请求).
如果endResponse = true(或者如果使用了其他重载),则抛出异常并立即终止当前请求.
这就是Response.Redirect(url,true)的工作原理.它抛出ThreadAbortException以中止线程.只是忽略那个例外.(我认为它是一个全局错误处理程序/记录器,你在哪里看到它?)
一个有趣的相关讨论是否认为Response.End()有害?
| 归档时间: |
|
| 查看次数: |
139360 次 |
| 最近记录: |