龙霖天网
龙霖学习园地
posts - 6,  comments - 2,  trackbacks - 0

今天在做一个系统的时候需要用到页面跳转,一般来说就是三种方法:

1、 response.redirect 需要注意的是跳转后内部空间保存的所有数据信息将会丢失,所以需要用到session

  2、 server.transfer 这个方法的重定向请求是发生在服务器端,所以浏览器的url地址仍然保留的是原页面的地址!

  3、 sever.execute 这个方法主要是用在页面设计上面,而且他必须是跳转同一站点下的页面。

 

不过在具体的时候用到页面跳转的时候,虽然能够跳转过去,但是总是会出现异常。如果你试图用try,catch捕获异常的并将异常的路径打出来的时候就会发现问题:页面正常跳转了,同时也出现了异常。

网上有一个帖子是解决这个问题的,我摘过来了并以我自身的尝试将对此补充一点:

下面是帖子的原文(地址:http://hi.baidu.com/lyh0702/blog/item/e121588277bbb7a10cf4d241.html

在项目里负责异常处理部分:异常信息的写入,读取,查看,因此就可以看到各种异常,受益匪浅
看到有N多的“线程正被中止”异常,而且来自同一个页面。
System.Threading.ThreadAbortException: 线程正被中止。
at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo) at System.Web.HttpResponse.End()
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at RPM.Page.LogInHR.btnLogin_Click(Object sender, EventArgs e)
in c:\inetpub\wwwroot\rpm_2\page\login\loginhr.aspx.cs:line 363
虽然捕获了,但并没有跳转到错误页面,但这个信息是在错误页面被写入数据库的!
我做了个试验,在异常信息查询页面跳转到异常信息一览页面
引发异常的页面:
try
     {
      // 异常一览页面
      Server.Transfer("../SystemManagement/ErrorReportView.aspx",false);
     }
     catch (Exception ex)
     {
      HttpContext.Current.Session["CurrentError"] = ex.ToString();
      HttpContext.Current.Session["CurrentErrorUrl"] = HttpContext.Current.Request.Url.ToString();
      // 跳转到异常信息显示页面
      HttpContext.Current.Server.Transfer("ErrorReport.aspx",false);
     }
异常信息显示页面对异常的处理:
string errortip = "<h4>" + Resources["MEMO_346"] + "</h4>" + "<br><br>";

      string error =
       "在页面:" + "<br>"
       + (string)Session["CurrentErrorUrl"] +"<br>"
       + "发生了如下异常:" + "<br>"
       + (string)Session["CurrentError"];
    
      // 部署时 不要显示异常信息!
      lblErrorMessage.Text = errortip + error;
      // 写入数据库
      LCW.RPM.BLL.ErrorReport errorReport = new LCW.RPM.BLL.ErrorReport();
      LCW.RPM.Model.ErrorReportInfo errorInfo = new LCW.RPM.Model.ErrorReportInfo();
      errorInfo.Content = error;
      errorInfo.UserName = "sa";
      errorReport.Insert(errorInfo);
也就是说实际上,确实跳转到了异常处理页面,并执行了代码,但没等到页面显示,就又跳到了异常信息一览页面,但此时并没有将刚才的异常查询出来,需要刷新页面才会出来。看来确实存在终止线程的问题
MSDN是这么说的:
ThreadAbortException 的引发条件:对 End 的调用已经终止当前请求。

Redirect 调用End,该方法在完成时引发 ThreadAbortException 异常。

End、Redirect 和Transfer的调用在当前响应提前结束时引发一个 ThreadAbortException。

End(HttpResponse.End )方法的说明:

将当前所有缓冲的输出发送到客户端,停止该页的执行,并引发 Application_EndRequest 事件。

ThreadAbortException:

在调用 Abort方法以销毁线程时,公共语言运行库将引发 ThreadAbortExceptionThreadAbortException 是一种可捕获的特殊异常,但在 catch 块的结尾处它将自动被再次引发。引发此异常时,运行库将在取消线程前执行所有 finally 块。由于线程可以在 finally 块中进行未绑定的计算,因此必须调用Join方法以保证线程已死亡。Join 是一个阻塞调用,它要到线程实际停止执行后才返回。

想不太明白

Update:

看了晓风残月 写的一篇文章 Response.Redirect 与 异常(线程正在中止) ,提到一文

原来    HttpContext.Current.Server.Transfer("ErrorReport.aspx",false);
是把异常挂起了,所以代码照样执行

按照文章试验了一下:

Response.Redirect(url)等同于Response.Redirect(ur,true),有异常

Response.Redirect(url,false),无异常

 

Server.Execute(url)无异常

 

Server.Transfer(url)等同于Server.Transfer(url,true)和Server.Transfer("ErrorReportView.aspx",false);都会出现异常

 

总之,要想避免异常,就用Response.Redirect(url,false)或Server.Execute(url)。

关于这三者的区别,另开新帖说明。

ps:

偶然发现Server.Execute(url)可以实现那种弹出框提示后紧接着跳转页面的需求,而其他两种情况下弹出框提示信息都不会显示。

注:如果使用 try 、catch 处理包含Response.Redirect    语句代码,总是能捕捉到异常:线程正在中止,
其实不仅仅Response.Redirect 会,Response.End 和 Server.Transfer 也是一样的情况,本质的原因的原因是Response.End 方法停止页的执行,并将该执行变换到应用程序的事件管线中的 Application_EndRequest 事件, Response.End 后面的代码行将不执行。通常认为Response.End 方法是线程的非正常结束,因此MS就在内部抛出ThreadAbortException 异常,而Response.Redirect 和 Server.Transfer 这两种方法都在内部调用 Response.End。

我对此做一点补充,我尝试了各种方法,最后我用的是Page.Response.Redirect("Allowed/Default.aspx");没有出现上述异常问题。其实这个问题的具体原因我也不知道,也许正是那个帖子说的呢。

posted on 2009-01-09 19:14 龙霖 阅读(1434) 评论(1)  编辑 收藏 引用 所属分类: .net

FeedBack:
# re: ASP页面跳转
2009-07-20 12:11 | d
d  回复  更多评论
  
只有注册用户登录后才能发表评论。

<2024年10月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

搜索

  •  

最新评论

阅读排行榜

评论排行榜