- PR -

Global.asaxでSession変数が保存出来ない…(ステートサーバ)

1
投稿者投稿内容
Cookie
ベテラン
会議室デビュー日: 2002/11/05
投稿数: 59
投稿日時: 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や基本データ型でも
消えてしまうので、原因がわかりません。

考えられる原因や打開策など、ご意見がいただけたら幸いです。
よろしくお願いします。
Cookie
ベテラン
会議室デビュー日: 2002/11/05
投稿数: 59
投稿日時: 2004-04-06 11:35
補足です。

GlobalLastExceptionの定義が抜けてますが、
プロシージャの外でException型で定義してあります。
プロシージャ内でDimで宣言したりいろいろ試してみましたが
そこはあまり関係なかったので、気にしないで下さい。
AC
会議室デビュー日: 2003/01/14
投稿数: 15
お住まい・勤務地: 東京都
投稿日時: 2004-04-13 00:43
Cookieさん、初めまして。

引用:


 @ アプリケーションレベルのエラーが発生した時に
   Global.asaxのApplication_Errorハンドラでキャッチ
         ↓
 A GetLastErrorメソッドで発生した例外を取得し、Session変数に保存★
         ↓
 B エラーページに遷移
         ↓
 C エラーページ側でSession変数を取得し、例外を解析表示




今のプロジェクトで同じことをやっています。
同じ様にエラーページで、
(あるエラーに限って)Session変数が取れませんでした。

「あるエラー」というのは、
Sessionから、ある変数(ユーザID)が取得できなかったらラーにする処理
だったのですが
実はそのエラーが発生しているとき、というのは
ユーザIDが取れないどころか、SessionTimeoutしていた、という状況でした。


切れているSessionに値をセットできて、
しかし取れない、というのがどうにも私には理解できないのですが・・・

まさかとは思いますが・・・ご参考までに(汗
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2004-04-13 11:55
興味があったので自分も試してみました。
結果は、Cookieさんとちょこっと違いInProcでもステートサーバーでもエラーページにてSession変数から値を取り出すことが出来ませんでした。。。
(ちとInProc時の動作がCookieさんと違うのが気になりますが)

で、回避策ですがエラーページに遷移するのにRedirectを利用しているところを、Server.TransferにすればエラーページでもSession変数から値を取り出せることが分かりました。
(Redirectと意味合いが変わってしまいますが)

Redirectを使うとなんで消えちゃうんでしょうね。。。Redirectすると内部的にThreadAbortExceptionが発生しているのが関係しているのでしょうか。。。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-04-13 12:20
引用:

noderaさんの書き込み (2004-04-13 11:55) より:

Redirectを使うとなんで消えちゃうんでしょうね。。。Redirectすると内部的にThreadAbortExceptionが発生しているのが関係しているのでしょうか。。。


 Redirectだと、いったんクライアントに処理をすべて投げ、クライアントがリダイレクト先に要求をするからです。Server.Transferだと、サーバ上でプロセスを置き換えます。この辺、MSDNに注意書きがしてあったと思います。


ACさん:
> 切れているSessionに値をセットできて、しかし取れない、
 切れているのにセットできるのは、新しいセッションが張られるからです。HttpSessionState.IsNewSessionで、新しいセッションかどうかがわかります。取れないのは謎。
Cookie
ベテラン
会議室デビュー日: 2002/11/05
投稿数: 59
投稿日時: 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

スキルアップ/キャリアアップ(JOB@IT)