1

オーバーライドされたPageOnUnloadでメソッドを実行していますが、Page_PreRenderメソッドが実行されている場合に限ります。

明らかに、Page_PreRenderにいるときにクラスレベルのブール値を反転してOnUnloadでチェックできますが、Page_PreRenderが実行されたことを確認するより本質的な方法がある場合は、それを使用したいと思います。

何か案は?

考えてくれてありがとう。

更新:私の質問を少し言い換えさせてください。Pageライフサイクルに固有の簡単な方法があるかどうかの答えを探しています。おそらくASP.Netフレームワークによって設定されるプロパティであり、Page_PreRenderの実行後とPage_PreRenderの実行後では異なるものです。走りません。

現在、Page_PreRenderにブール値を設定して、実行されたかどうかを通知しています。それは機能しますが、余分なブールチェックを追加せずに同じことを達成する方法がある場合、このソリューションは好きではありません。Page_PreRender中に発生するイベントを作成することは、可能であれば避けたいのと同じレベルの冗長性です。

4

7 に答える 7

3

(別の投稿のコメントで)Response.Redirect() を呼び出すと、ThreadAbortException がスローされ、OnPreRender() イベントが呼び出されないため、問題が発生することがわかります。それでは、代わりにこれを使用してみませんか?:

Response.Redirect("~/SomePage.aspx", false);

そこに表示される「false」は、ページの実行がすぐに終了するかどうかを示します。デフォルトでは、Response.Redirect() は「true」を使用します。OnLoad() イベントに必要なものがすべて含まれるように OnPreRender() イベントを実行する必要がある場合は、「false」に設定し、Response.Redirect を呼び出した後に Page_Load() の最後にジャンプするようにしてください。 () または実行後に実行されるコードは実行しても問題ありません。

おそらく、オーバーロードされた Response.Redirect() メソッドを使用して「false」を渡すという考えが気に入らないので、そのルートに行かなかったのです。ここにあなたの心を揺さぶるのに役立つかもしれないいくつかのドキュメントがあります:

Microsoft は、「true」を指定すると HttpResponse が呼び出されるため、「endResponse パラメーターに false を渡すことをお勧めします」と述べています。元のリクエストのEnd() メソッドを呼び出し、完了時に ThreadAbortException をスローします。Microsoft は続けて、「この例外は Web アプリケーションのパフォーマンスに悪影響を及ぼします」と述べています。ここの「備考」セクションを参照してください: http://msdn.microsoft.com/en-us/library/a8wa7sdt.aspx

これは昨年 MSDNに投稿されました。

End メソッドも、私の「絶対に使用しない」リストに含まれています。リクエストを停止する最善の方法は、HttpApplication.CompleteRequest を呼び出すことです。End メソッドが存在するのは、1.0 がリリースされたときに従来の ASP との互換性を維持しようとしたためです。従来の ASP には、ASP スクリプトの処理を終了する Response.End メソッドがあります。この動作を模倣するために、ASP.NET の End メソッドは ThreadAbortException を発生させようとします。これが成功すると、呼び出し元のスレッドは中止され (非常にコストがかかり、パフォーマンスが低下します)、パイプラインは EndRequest イベントにジャンプします。もちろん、ThreadAbortException が成功した場合は、それ以上コードを呼び出す前にスレッドがアンワインドすることを意味するため、End を呼び出すと、その後はコードを呼び出さないことを意味します。End メソッドが ThreadAbortException を発生させることができない場合、代わりに応答バイトをクライアントにフラッシュしますが、これを同期的に行うためパフォーマンスが非常に悪く、End の後のユーザー コードの実行が完了すると、パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。しかし、これは同期的に行われるため、パフォーマンスが非常に悪く、End の後のユーザー コードの実行が完了すると、パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。しかし、これは同期的に行われるため、パフォーマンスが非常に悪く、End の後のユーザー コードの実行が完了すると、パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。

MSDN が示唆するように、Response.Redirect() を呼び出した後にこの行を追加したところ、すべてが同じように実行されているように見えました。4.0 で必要かどうかはわかりませんが、問題はないと思います。

HttpContext.Current.ApplicationInstance.CompleteRequest();

更新 1

Response.Redirect() の呼び出しで "false" を使用すると、ThreadAbortException を回避できますが、ページでスローされる可能性があるその他の未処理の例外はどうでしょうか? これらの例外により、OnPreRender() なしで OnUnload() が呼び出されるという問題が引き続き発生します。誰もがこれを回避するように提案しているように、OnPreRender() でフラグを使用できますが、ハンドルされていない例外をスローしている場合は、より大きな問題が発生しており、とにかくエラー ページにリダイレクトする必要があります。Unhandled Exceptions はすべてのポストバックでスローする予定のものではないため、Try-Catch で OnUnload() ロジックをラップした方がよいでしょう。例外をログに記録して監視している場合は、OnUnload() イベントで NullReference 例外をログに記録する直前に未処理の例外がスローされていることがわかり、どれを無視するかがわかります。

更新 2

OnUnload() を Try-Catch でラップしたままにする必要がありますが、これが本当に探しているものだと思います (Response.Redirect を呼び出すとき、または Unhandled Exception の後にエラー ページにリダイレクトするときに IsRequestBeingRedirected が true になることを思い出してください)。 .:

if (HttpContext.Current.Response.IsRequestBeingRedirected != true)
{
    //You're custom OnUnload() logic here.
}

これにより、OnUnload() イベントでカスタム ロジックを処理することが安全かどうか (または処理する価値があるかどうか) がわかります。おそらくこれで始めるべきだったと思いますが、今日は多くのことを学んだと思います。;)

注: Server.Transfer() を使用すると、恐るべき Response.End() も呼び出されます。これを回避するには、代わりにpreserveForm属性を「false」に設定して Server.Execute() を使用します。

Server.Execute("~/SomePage.aspx", false);
return;

注: Server.Execute("~/SomePage.aspx", false); に関すること IsRequestBeingRedirected は false になりますが、OnPreRender() は引き続き実行されるため、心配する必要はありません。

于 2011-05-28T08:33:15.530 に答える
1

答えは「はい」です。常に可能ですが、常にそうとは限りません:) Reflectionコードによると、ScriptManagerクラスにはプライベートboolフィールドが含まれています。これは、内部インターフェイスイベントの処理中_preRenderCompletedに設定されます。リフレクションを使用して、結果のオブジェクトからこのフィールドを取得できますtrueIPagePagePreRenderCompleteScriptManager.GetCurrent(page)

于 2011-05-31T07:32:16.520 に答える
0

PreRender イベントで発生するカスタム イベントを作成します。

于 2011-05-24T19:28:56.503 に答える
0

ASP.NET エンジンはその状態を暗黙のうちに認識しているため、実際にはそれを必要としないため、何らかの状態が保存されているとは思いません。

.NET Reflector で検索すると、ページ レンダリング イベントがこの内部 System.Web.UI.Page メソッドから発生しているようです。

private void ProcessRequestMain(bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint)

あなたはそれを見ることができます、状態の概念はありません。取得できる唯一の情報はトレースです。Unload イベントにアクセスできる場合は、トレースにアクセスする必要がありますか? または私は何かが恋しい:-)

トレースは実際にはデータセットの秘密であるため (こちらの回答を参照してください: Logging the data in Trace.axd to a text/xml file )、情報を取得できる可能性があります。ただし、本番環境では trace=true を設定することはお勧めしません...

于 2011-05-28T07:18:05.130 に答える
0

これが何を意味するのか正確にはわかりません。ASP.NET Page Lifecycle によると、PreRender常に前に実行されUnloadます。このイベント内で if 条件を実行し、条件が満たされているかどうかPreRenderをテストしたい場合はUnload、ページ クラスのブール フィールドを使用することをお勧めします。

于 2011-05-19T16:35:55.850 に答える
0

page ディレクティブに trace=true を追加します。

于 2011-05-19T16:36:03.403 に答える
0

PreRender イベント ハンドラーでブール フィールドを設定し、Unload イベント ハンドラーで設定されているかどうかを確認します。

于 2011-05-24T18:21:02.450 に答える