2009年5月20日水曜日

Application_Errorで嵌る。

今回のはまりはGlobal.asaxのApplication_Error()とエラーページについて、

最初の実装では、
Global.asax.csのApplication_Error()でこんな感じにして、

protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Session["errormessage"] = ex.Message;
Server.Transfer("Error.aspx");
}

Error.aspx.csでは、こんな感じにしてみた。
protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Text = (string)Session["errormessage"];
}

そうすると、なぜか、エラーページのメッセージにはいつもハンドルされていないエラーの旨のメッセージしかでなかった。
なぜかはわからないが、とりあえず、Server.GetLastError()で取得したエラーについて、innerErrorが存在する場合はinnerErrorを発生した例外として扱ってみた。

で、うまくいくように見えたのだけれど、nopage.aspx(存在しないページ)にアクセスすると、Application_Error()の処理のSessionに値を詰め込むところでエラーが発生した。
多分、aspxページが存在しないとSessionが扱える状態になる前にApplication_Errorが呼ばれたからじゃないかな?
というわけで、Application_Errorを以下のような感じに、
Server.Transfer("Error.aspx?errormessage="+ HttpUtility.UrlEncode(ex.Message));

Error.aspx.csのPage_Loadでは以下のような感じにしてみた。
TextBox1.Text = HttpUtility.UrlDecode( Request["errormessage"]);


そうすると、存在しないページにアクセスしたときも意図通りの動作になったが、、、

次は、@Pageディレクティブで、ValidateRequest="true"のページで、<a>などの入力をしてみると、Error.aspx(このページは@PageディレクティブにValidateRequest="false"としているにもかかわらず)の処理で、Request["errormessage"]のタイミングでも、ValidateRequestの例外が発生する。
多分、Server.Transfer()で行っているので、Error.aspxの処理の前の前段パイプライン処理が走っていないから、Error.aspxのページディレクティブを参照していなくて、元ページのValidateRequestの値が引き続き使われているからだろうなぁと想像しますが、かといってResponse.Redirect()にして、URLをさらすわけにもいかず、、、結局web.configでValidateRequest="false"にしてしまって様子見。。。はぁ。

0 件のコメント: