6

重複の可能性:
Response.Redirect により System.Threading.ThreadAbortException が発生する

ASP/C#.NET (MVC ではなく Web フォーム)

更新: 関連する投稿が見つかりました (これは重複している可能性があります):なぜ Response.Redirect が System.Threading.ThreadAbortException を引き起こすのですか?

~ ~ ~

かなりの調査の後、一般に、Response.Redirect() を使用する場合、System.Threading.ThreadAbortException を回避するために、2 番目のパラメーターに FALSE を渡す方がよいということがわかりました。( http://blogs.msdn.com/b/tmarq/archive/2009/06/25/correct-use-of-system-web-httpresponse-redirect.aspx )

私の質問は、「第 2 パラメーターに false が渡されたときに、リダイレクト後に発生するページ イベントで処理を管理 (つまり、スキップ) するための推奨される方法 (パターン) はありますか?」です。

これは、Page_Load() で有効期限が切れたセッションをチェックしてリダイレクトしているときに、私にとって主に問題になります。リダイレクトするたびに「_Redirected」フラグを設定し、すべてのイベントの先頭でそのフラグを確認する必要があるのは非常に面倒です。以前は、2 番目のパラメーターに常に TRUE を渡していたので、これについて心配する必要はありませんでした。

以下は、私がやりたくないことを示すコードです (各イベントを処理する前に _Redirected をチェックしてください)。おそらく、私が探しているのは、より優れたセッション有効期限処理パターンです。

この処理を改善する方法についての提案は、大歓迎です。

private bool _Redirected = false;    

protected void Page_Load(object sender, EventArgs e)
{
  if (Session["key"] == null)
  {
    Response.Redirect("SessionExpired.aspx", false);
    Context.ApplicationInstance.CompleteRequest();

    _Redirected = true;
  }       
}

protected void Page_PreRender(object sender, EventArgs e)
{
  if (!_Redirected)
  {
    // do Page_PreRender() stuff...
  }
}

protected void Button1_Click(object sender, EventArgs e)
{
  if (!_Redirected)
  {
    // do Button1_Click() stuff...

    Response.Redirect("Button1Page.aspx", false);
    Context.ApplicationInstance.CompleteRequest();

    _Redirected = true;
  }
}

protected void Button2_Click(object sender, EventArgs e)
{
  if (!_Redirected)
  {
    // do Button2_Click() stuff...

    Response.Redirect("Button2Page.aspx", false);
    Context.ApplicationInstance.CompleteRequest();

    _Redirected = true;
  }
}

~ ~ ~

[2013 年 1 月 24 日] https://stackoverflow.com/users/2424/chris-lively (ありがとう、ところで) に応えて、あなたがテストしたものと似ていると思われる単純化されたコードを次に示します。Page_Load() で .CompleteRequest() を使用して Response.Redirect(url, false) を実行した後、ポストバックで Button1_Click() が実行されるのをまだ確認しています。

protected void Page_Load(object sender, EventArgs e)
{
  if (this.IsPostBack)
  {
    Response.Redirect("Redirect.aspx", false);
    Context.ApplicationInstance.CompleteRequest();
  }
}

protected void Button1_Click(object sender, EventArgs e)
{
  Response.Write("Button1 clicked!");
}

この動作は、上記の更新で指摘した同様の投稿に対するこの応答https://stackoverflow.com/a/12957854/1530187によって裏付けられています。

リダイレクト後にページが実行され続ける原因となる、私が間違っていることについて何か考えはありますか?

4

1 に答える 1

7

あなたはかなり良い記事を参照しましたが、あなたのコードは、これを「正しく」実行する方法として著者が提案したことを反映していません。すなわち:

protected void Page_Load(object sender, EventArgs e)
{
  if (Session["key"] == null)
  {
    Response.Redirect("SessionExpired.aspx", false);
    Context.ApplicationInstance.CompleteRequest();
  }       
}

更新
非常に単純なサンプル アプリケーションをまとめました。フォーム ページが 2 つしかありませんでした。
最初のページには、response.write を実行するボタンがありました。この行にブレークポイントを置きます。page_load メソッドでは、リダイレクトの直後に への呼び出しを配置し​​ましたCompleteRequest。このリダイレクトの発生は、ページがポストバックされた場合に発生するように設定されていました。

2 番目のページで行ったのは、「hello」を発行することだけでした。

次にアプリケーションを実行すると、最初のフォームが表示されました。ボタンをクリックしました。ブレークポイントにはヒットせず、リダイレクトされました。これはまさに私が期待していたことでした。つまり、page_load メソッドはポストバックをキャッチし、リダイレクトを実行し、ページをさらに処理することなく、すぐにリクエストを完了しました。

if (!_Redirected)これは、ボタンのクリックごとにコードを挿入する理由がまったくないことを意味します。この回答の上部にあるコードをコピーして貼り付けるだけです。これらのクリックが呼び出されるのを防ぎます。

于 2013-01-23T00:45:39.807 に答える