- - PR -
Global.asaxでSession変数が保存出来ない…(ステートサーバ)
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2004-04-06 11:33
いつもお世話になっております。
Global.asaxでSession変数が保存出来なくて困っております。 (過去スレッドでステートサーバでのSession変数保存について議論されていたのですが、 少し内容が違うので別にスレッドを立てさせていただきました。) やりたい処理を簡単にまとめると、こんな感じです。 @ アプリケーションレベルのエラーが発生した時に Global.asaxのApplication_Errorハンドラでキャッチ ↓ A GetLastErrorメソッドで発生した例外を取得し、Session変数に保存★ ↓ B エラーページに遷移 ↓ C エラーページ側でSession変数を取得し、例外を解析表示 ★の処理はこのようになっています。----------------------------------------- Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) '最後に発生した例外を取得しキャスト GlobalLastException = Server.GetLastError().GetBaseException() Session("MyException") = GlobalLastException System.Diagnostics.Debug.Assert(False) '専用ページにリダイレクト Response.Redirect("MyError.aspx") Response.End() End Sub ------------------------------------------------------------------------ デバッグ実行してトレース&ウォッチしてみたところ、Global.asax内では Session変数に確かに例外が入っているのですが、MyError.aspxに遷移したとたんに Nothingになってしまいます。何が原因なのでしょうか? ちなみに、InProcサーバで実行してみた時は、同じソースでちゃんとSession変数が 保存されていました。Exceptionクラスは暗黙的にシリアライズされるはずなので 問題ないと思うのですが、シリアライズの必要のないただのStringや基本データ型でも 消えてしまうので、原因がわかりません。 考えられる原因や打開策など、ご意見がいただけたら幸いです。 よろしくお願いします。 | ||||
|
投稿日時: 2004-04-06 11:35
補足です。
GlobalLastExceptionの定義が抜けてますが、 プロシージャの外でException型で定義してあります。 プロシージャ内でDimで宣言したりいろいろ試してみましたが そこはあまり関係なかったので、気にしないで下さい。 | ||||
|
投稿日時: 2004-04-13 00:43
Cookieさん、初めまして。
今のプロジェクトで同じことをやっています。 同じ様にエラーページで、 (あるエラーに限って)Session変数が取れませんでした。 「あるエラー」というのは、 Sessionから、ある変数(ユーザID)が取得できなかったらラーにする処理 だったのですが 実はそのエラーが発生しているとき、というのは ユーザIDが取れないどころか、SessionTimeoutしていた、という状況でした。 切れているSessionに値をセットできて、 しかし取れない、というのがどうにも私には理解できないのですが・・・ まさかとは思いますが・・・ご参考までに(汗 | ||||
|
投稿日時: 2004-04-13 11:55
興味があったので自分も試してみました。
結果は、Cookieさんとちょこっと違いInProcでもステートサーバーでもエラーページにてSession変数から値を取り出すことが出来ませんでした。。。 (ちとInProc時の動作がCookieさんと違うのが気になりますが) で、回避策ですがエラーページに遷移するのにRedirectを利用しているところを、Server.TransferにすればエラーページでもSession変数から値を取り出せることが分かりました。 (Redirectと意味合いが変わってしまいますが) Redirectを使うとなんで消えちゃうんでしょうね。。。Redirectすると内部的にThreadAbortExceptionが発生しているのが関係しているのでしょうか。。。 | ||||
|
投稿日時: 2004-04-13 12:20
Redirectだと、いったんクライアントに処理をすべて投げ、クライアントがリダイレクト先に要求をするからです。Server.Transferだと、サーバ上でプロセスを置き換えます。この辺、MSDNに注意書きがしてあったと思います。 ACさん: > 切れているSessionに値をセットできて、しかし取れない、 切れているのにセットできるのは、新しいセッションが張られるからです。HttpSessionState.IsNewSessionで、新しいセッションかどうかがわかります。取れないのは謎。 | ||||
|
投稿日時: 2004-04-13 13:13
ACさんnoderaさんJittaさん、丁寧なご返答ありがとうございました!
まず早速noderaさんの回避策で試してみた結果をご報告しますが、 Stateサーバのまま無事にSession変数を取得出来ました。ありがとうございます! >ACさん ご意見ありがとうございました。参考になりました。 ACさんの場合は、その特定のエラー以外は取得できていたということですよね。 ACさんの現象と合わせて考えると、こちらで、Global.asax内でだけSession変数が 格納されていた理由もなんとなくわかりました。(同名のキーのSession変数を あらかじめ用意していたらGlobal.asaxを抜けたときに元の値に戻ったので、 多分別のセッションになってしまっていたのでしょう。) セットできたのに取れないということは、取ろうとして見ているのもまたさらに 新しいセッション、とかなんでしょうか…? >noderaさん 決定的な打開策を本当にありがとうございました。非常に助かりました! ![]() ほぼ諦めていたところだったので、本当に… (InProcサーバの時の動作の違いが気になりますね。 私のところでは書き込みの通り、RedirectでもInProcは○、Stateは×でした。 Jittaさんの説明と一緒に考えると「一度クライアントに処理を投げても インプロセスだからまだ残っている」とかそんな感じかなと思ったのですが、 なぜnoderaさんと動きが違うのでしょうね。? ちなみに、ThreadAbortExceptionはどちらでも暗黙的に発生するみたいです。) >Jittaさん RedirectでなくTransferを使用するべきだったんですね。 その理由もJittaさんのご説明でよく理解できました。 両者の違いについてはある程度は知ってはいたのですが、他プログラムの開発で ほぼ区別なく使用していたこともあり、ここでその違いによる影響があると なかなか気づきませんでした。私の勉強不足です。 今後参考に致します。 レスして頂いた方々、貴重なご意見を本当にありがとうございました。 |
1