本文可協助您解決當您使用 Server.Transfer 中的 HTTPHandler 方法將控件從某個頁面傳送至 ASP.NET Web 應用程式中的另一個頁面時,可能會擲回錯誤的問題。
原始產品版本: ASP.NET
原始 KB 編號: 817266
徵兆
當您使用 Server.Transfer 中的 HTTPHandler 方法,將控件從某個頁面傳輸到 ASP.NET Web 應用程式中的另一個頁面時,您可能會收到下列錯誤訊息:
System.Threading.ThreadAbortException:正在中止線程。 時間
System.Threading.Thread.AbortInternal() at System.Threading.Thread.Abort() at
System.Web.HttpResponse.End() 的 System.Threading.Thread.Abort(Object stateInfo) at
System.Web.HttpServerUtility.Transfer(字符串路徑,布爾值 preserveForm)
原因
當您呼叫 Server.Transfer時,ASP.NET 會在內部呼叫 Server.Execute 方法來傳輸控件,並呼叫 Response.End 方法來結束目前頁面的處理。
Response.End 結束頁面執行並呼叫 Thread.Abort 方法。 方法 Thread.Abort 會導致 ThreadAbortException 錯誤訊息出現。
因應措施
若要解決此問題,請使用 Server.Execute ,而不是 Server.Transfer 在 的 方法HTTPHandler中使用 ProcessRequest 。 修改 ProcessRequest 過的方法如下所示:
C# 範例程式碼 (英文)
public void ProcessRequest(HttpContext context) { try { context.Server.Execute("WebForm1.aspx"); } catch(System.Exception e) { context.Response.Write(e.StackTrace); context.Response.Write(e.ToString()); } }Visual Basic 範例程序代碼
Public Sub ProcessRequest(ByVal context As HttpContext) _ Implements IHttpHandler.ProcessRequest Try context.Server.Execute("WebForm1.aspx") Catch e As Exception context.Response.Write(e.StackTrace) End Try End Sub
狀態
這是依照設計的行為。
重現行為的步驟
在 Microsoft Visual Studio 中,使用 Visual Basic 或 C# 建立新的 ASP.NET Web Form Application 專案。 根據預設, 會建立WebForm1.aspx 。 將專案 命名為 ServerTransferTest。
以滑鼠右鍵按兩下 WebForm1.aspx ,然後選取 [ 檢視 HTML 來源]。
以下列範例程式代碼取代現有的程式代碼:
<%@ Page %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:HyperLink id="HyperLink1" style="Z-INDEX: 101; LEFT: 324px; POSITION: absolute; TOP: 181px" runat="server" NavigateUrl="http://localhost/ServerTransferTest/test.ashx"> http://localhost/ServerTransferTest/test.ashx</asp:HyperLink> <asp:Label id="Label1" style="Z-INDEX: 102; LEFT: 292px; POSITION: absolute; TOP: 149px" runat="server">On Clicking this URL should not throw any exception</asp:Label> </form> </body> </HTML>按兩下 WebForm1.aspx 的設計檢視,然後使用下列範例程式代碼取代程式代碼後置頁面中的結束程式代碼:
C# 範例程式碼 (英文)
using System; using System.Web; using System.Web.UI.WebControls; namespace ServerTransferTest { /// <summary> /// Summary description for WebForm1. /// </summary> public class WebForm1 : System.Web.UI.Page { protected System.Web.UI.WebControls.Label Label1; protected System.Web.UI.WebControls.HyperLink HyperLink1; private void Page_Load(object sender, System.EventArgs e) { } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // CODEGEN: ASP.NET Web Form Designer requires this call. InitializeComponent(); base.OnInit(e); } /// <summary> /// Required method for Designer support - do not modify /// the contents of this method by using the code editor. /// </summary> private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion } }Visual Basic 範例程序代碼
Public Class WebForm1 Inherits System.Web.UI.Page Protected WithEvents Label1 As System.Web.UI.WebControls.Label Protected WithEvents HyperLink1 As System.Web.UI.WebControls.HyperLink 'Web Form Designer requires this call. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() End Sub Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: Web Form Designer requires this method call. 'Do not modify it by using the code editor. InitializeComponent() End Sub Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here End Sub End Class
在 [ 檔案] 功能表上,選取 [ 新增專案]。
在 [新增專案] 下,選取 [類別]。 在 [新增專案] 下的 [名稱] 文本框中,重新命名 類別
HelloWorldHandler,然後選取 [開啟]。以下列範例程式代碼取代類別檔案中的
HelloWorldHandler現有程式代碼:C# 範例程式碼 (英文)
using System.Web; namespace ServerTransferTest { public class HelloWorldHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { try { context.Server.Transfer("WebForm1.aspx", true ); } catch(System.Exception e) { context.Response.Write(e.StackTrace); context.Response.Write(e.ToString()); } } public bool IsReusable { // To enable pooling, return true here. // This keeps the handler in memory. get { return false; } } } }Visual Basic 範例程序代碼
Imports System Imports System.Web Public Class HelloWorldHandler Implements IHttpHandler Public Sub ProcessRequest(ByVal context As HttpContext) _ Implements IHttpHandler.ProcessRequest Try ' context.Server.Transfer("WebForm1.aspx", True) context.Server.Execute("WebForm1.aspx") Catch e As Exception context.Response.Write(e.StackTrace) End Try End Sub ' Override the IsReusable property. Public ReadOnly Property IsReusable() As Boolean _ Implements IHttpHandler.IsReusable Get Return True End Get End Property End Class
重複步驟 5 和 6 以新增另一個類別檔案。 重新命名類別檔案
HelloWorldHandlerFactory。以下列範例程式代碼取代類別檔案中的
HelloWorldHandlerFactory現有程式代碼:C# 範例程式碼 (英文)
using System.Web; namespace ServerTransferTest { public class HelloWorldHandlerFactory : IHttpHandlerFactory { public IHttpHandler GetHandler( HttpContext context, System.String requestType, System.String url, System.String pathTranslated) { HttpResponse Response = context.Response; Response.Write("<html>"); Response.Write("<body>"); Response.Write("<h1> Hello from HelloWorldHandlerFactory.GetHandler </h1>"); Response.Write("</body>"); Response.Write("</html>"); return new HelloWorldHandler(); } public void ReleaseHandler( IHttpHandler handler ) { } } }Visual Basic 範例程序代碼
Imports System Imports System.Web Public Class HelloWorldHandlerFactory Implements IHttpHandlerFactory Public Overridable Function GetHandler(ByVal context As HttpContext, _ ByVal requestType As String, ByVal url As String, ByVal pathTranslated As String) _ As IHttpHandler _ Implements IHttpHandlerFactory.GetHandler Dim Response As HttpResponse = context.Response Response.Write("<html>") Response.Write("<body>") Response.Write("<h1> Hello from HelloWorldHandlerFactory.GetHandler </h1>") Response.Write("</body>") Response.Write("</html>") Return New HelloWorldHandler() End Function Public Overridable Sub ReleaseHandler(ByVal handler As IHttpHandler) _ Implements IHttpHandlerFactory.ReleaseHandler End Sub End Class
開啟 web.config 檔案,然後在 區段中新增
<httpHandlers>區段<system.web>,如下所示:<configuration> <system.web> <httpHandlers> <add verb="*" path="*.ashx" type="ServerTransferTest.HelloWorldHandlerFactory,ServerTransferTest" /> </httpHandlers> ..... </system.web> </configuration>在 [偵錯] 功能表上,選取 [開始],然後在WebForm1.aspx上選取下列超連結:
http://localhost/ServerTransferTest/test.ashx