- PR -

[ASP.NET] Response.Redirect 後にボタンイベント発生?

投稿者投稿内容
とりまー
会議室デビュー日: 2007/07/20
投稿数: 9
投稿日時: 2007-10-11 15:34
こんにちは。

現在下記の内容でつまずいています。
最小コードやデバッグ環境ではいまのところ発生しない為、悩んでいます。

●環境
 ASP.NET2.0(VB.NET2005)
 IIS6.0(StateServer利用)

●質問事項
 1.Page_Load イベント発生後、各ボタンなどのイベントが発生するという認識で
  あっていますか?
 2.Page_Load イベント内で Response.Redirect を実行した場合には、ボタン押下
  の PostBack イベントは発生しないという認識であっていますか?
  仮に発生するとすればどういう時でしょうか?

●実装仕様
 a.ログイン画面でログインに成功したらセッション変数Aにログイン情報を格納。
 b.Page_Load イベント内で、セッション変数Aの有無をチェックし、無ければ
  タイムアウト画面へリダイレクト。

●現象
 タイムアウト設定の時間を超過してから、あるボタンを押下した時に、通常はタイム
 アウト画面へ遷移しますが、そのボタンの押下イベント(PostBack時)が走ってエラー
 で落ちる、という現象が「まれに」発生します。
 質問事項に書いた認識と実装が正しければ、発生し得ない現象なのですが。
 直接のエラー原因は、別のセッション変数を取得して値ありきで処理をしているが、
 実際にはデータがとれていなくて、 NullReferenceException が発生しています。
 NullReferenceException の発生はエラーログの出力結果からつきとめました。
 また常に同じ箇所でエラー発生する訳ではないのですが、セッション変数を取得して
 値ありきで処理している部分でエラーが発生、という点は共通しています。

●現状他
 とりあえず、Response.Redirect の直前にログ出力するようにしておき、エラーの
 再現時にログ確認をしようとしています。

 以上初歩的な事かもしれませんが、ご指摘・ご意見・ヒントなどあれば、お願いでき
 ますでしょうか。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-10-11 17:38
引用:
1.Page_Load イベント発生後、各ボタンなどのイベントが発生するという認識で
  あっていますか?
 2.Page_Load イベント内で Response.Redirect を実行した場合には、ボタン押下
  の PostBack イベントは発生しないという認識であっていますか?
  仮に発生するとすればどういう時でしょうか?

1はあってると思います。
2はResponse.Redirectの2番目の引数をfalseにした場合はボタン押下イベントは発生します。
trueにした場合や引数にurlのみ渡した場合は発生しないでしょう。

もうひとつはResponse.Redirectが実は発生していないケースが考えられます。
Response.Redirectの前で例外が発生していて、その例外をcatchで握りつぶしたりしていれば
ボタン押下イベントは発生するでしょうね。

遷移先のコードが走っているか(つまりResponse.Redirectを通ったか)も見てみるとよいでしょう。
とりまー
会議室デビュー日: 2007/07/20
投稿数: 9
投稿日時: 2007-10-11 18:16
べる様、ご指摘頂きありがとうございました。
私の認識が基本的には誤っていないという点について少々安心しました。

2.については、第二引数は指定していませんでした。
Response.Redirect 前に例外が発生する、という可能性をコードチェックしてみましたところ、 Try 句の開始から Response.Redirect 迄の間には、セッションから値を取り出してチェックするロジックのみ入っていました。また Catch 句では、ThreadAbortException は無視し、 Exception はリスローするようにしていますので、考えにくいと思いました。
ただ、Finally 句内でも Session 変数にアクセスしていましたので、この部分はもう少し検証してみる余地があると思っています。

尚、エラーは、Page_Error イベントで集中的に拾うようにしています。

ログ出力コードの投入などが、あまり自由にできない状態(ユーザテスト中)ですが、また何か変化ありましたら書込みさせて頂きます。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-10-11 20:13
その状況は、あなたが出したものでしょうか?
ユーザーさんが「なんかエラーになるんやけど?」と問い合わせてきて、原因を探っていくと、書いてあるような原因が考えられる、というようなことでしょうか。

発生したときのオペレーションが知りたいなぁ
同時接続数とかもかんけいするかなぁ?
いったん InProcにすると状況が変わったりするかも?
todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2007-10-11 20:21
引用:

●現象
 タイムアウト設定の時間を超過してから、あるボタンを押下した時に、通常はタイム
 アウト画面へ遷移しますが、そのボタンの押下イベント(PostBack時)が走ってエラー
 で落ちる、という現象が「まれに」発生します。



そういう現象が発生したと断言する根拠は?

引用:

 直接のエラー原因は、別のセッション変数を取得して値ありきで処理をしているが、
 実際にはデータがとれていなくて、 NullReferenceException が発生しています。



ログイン情報はセッションに保持されているが、何らかの原因で「別のセッション変数」が
消えてしまったとか。

プラウザの戻るボタンが押された場合やCTRL+Nキーで複数ウインドウを開いた場合にセッション変数の引渡しで問題があるケースが考えられます。
過去ログ参照

[ メッセージ編集済み 編集者: todo 編集日時 2007-10-11 20:21 ]

[ メッセージ編集済み 編集者: todo 編集日時 2007-10-11 20:22 ]
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-10-11 22:06
あと例えば、javascriptでなんらかの細工をしてるケース等で、タイミング的な問題でsubmitが
2重に走っちゃうことがなくもないです。その場合、片方はエラーになったけどもう片方は
ボタン押下イベントを通ったとすると、例の現象が発生したようにみえるかもしれませんね。
あくまでもひとつの心当たりです。

やはり「そういう現象が発生したと断言する根拠は?」ってことになります。
とりまー
会議室デビュー日: 2007/07/20
投稿数: 9
投稿日時: 2007-10-12 11:41
皆様、書き込みありがとうございます。

●Jitta様:
引用:

ユーザーさんが「なんかエラーになるんやけど?」と問い合わせてきて、原因を探っていくと、書いてあるような原因が考えられる、というようなことでしょうか。


そうなのです。私自身はまだ再現できず、現場も目撃できずにいます。「タイムアウト後のボタン押下で発生するらしい」というのは現場SEからの話です。
InProc も試してみたいですね。




●todo様:
引用:

そういう現象が発生したと断言する根拠は?


痛いところをつかれました。実際問題として断言できておりません。そこが弱いところでして、ログを投入して詳細を調べたいと、SEに要求しておるところです。
引用:

ログイン情報はセッションに保持されているが、何らかの原因で「別のセッション変数」が
消えてしまったとか。


可能性としてはあるかもしれませんが、色々な場所でセッション変数が消えて(エラー箇所が異なるため)、ログイン情報のセッション変数だけが残るというのも考えにくいなぁ、と思ったものですから。
引用:

プラウザの戻るボタンが押された場合やCTRL+Nキーで複数ウインドウを開いた場合にセッション変数の引渡しで問題があるケースが考えられます。


一応、特殊キーの入力は JavaScript でガードしてますが、特殊なマウスにアサインされた場合に防げないことは、お客さんには了承頂いてます。確かにその部分も要再確認だな、と気づきました。



●べる様:
引用:

2重に走っちゃうことがなくもないです。その場合、片方はエラーになったけどもう片方は
ボタン押下イベントを通ったとすると、例の現象が発生したようにみえるかもしれませんね。
あくまでもひとつの心当たりです。


この点は私も漠然と懸念していましたが、知識不足・調査不足によりよく判っておりません。
2重 Submit が走った場合に複数スレッドで動作したりするのか、そうすると先発 Submit でセッション変数を参照後に消した場合に、後発 Submit ではセッション変数が取れなかったりするのか、といった辺りについて、ご教授もしくは参考サイト等ご提示頂けましたら大変助かります。
一応 JavaScript では、 body.onbeforeunload イベントを使って、多重サブミットが走らないようにガードを実装しております。



以上よろしくお願いいたします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-10-12 15:39
セッションIDもログしたほうがいいかもね
別のセッションになっていたら、見当違いの原因を探していることになるから

ステートサーバは、再起動しないんだったっけ?

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