WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

ReportViewer と Session

by WebSurfer 2015年9月7日 15:22

ReportViewer は Session を使うという話を書きます。

IE で ReportViewer を表示

上の画像は、ReportViewer を使用してパラメーターを含む詳細 (RDLC) レポートを作成する というチュートリアルに従って作ったものですが、どこにも明示的に Session を使うようなコードは含まれていません。

ところが、このページを要求すると、下の画像(Fiddler2 でキャプチャしたもの)のように応答ヘッダにセッション Cookie が設定され(画像の赤枠で囲った部分)、Session の使用が開始されます。

応答ヘッダのセッション Cookie

知ってました? 実は自分は知らなかったです。(汗) 最近まで ReportViewer と Session は何の関係もないと思っていましたが、MSDN フォーラム でのやり取りを通じてこのことを知りました。

MSDN Blog の記事 Did Your Session Really Expire? によると、ReportViewer は再生するのが簡単ではないデータを保存するのに Session を使うとのことです。

そして、ポストバックの際などに期待したデータが Session にないと AspNetSessionExpiredException をスローするとのことです。

AspNetSessionExpiredException 例外がスローされる原因として次のことが書かれています:

  1. 本当にセッションがタイムアウトした。(例:ping をかけてタイムアウトにならないようにしているが、サーバーが忙しいとか接続が不安定で失敗した)
  2. 要求を処理しているサーバーにセッションがない。(例:セッションのモードが InProc で、Web Garden / Farm 構成になっているとか、ワーカープロセスがリサイクルされた)
  3. ブラウザがクッキーを受け付けない設定になっている。

上記 1 のことは MSDN ライブラリの ReportViewer.KeepSessionAlive プロパティ に書かれています。デフォルトは true で、セッションがタイムアウトしないように自動的に ping がかかります。

上記 2 のワーカープロセスのリサイクルによる Session の消失を防ぐためには、Session の格納場所を InProc ではなく、StateServer または SQLServer にするのがよさそうです。商用に使うのであれば、InProc モードは論外という意見もあるようですし。設定方法の詳細は MSDN ライブラリの記事 セッション状態モード を見てください。

Tags: ,

ASP.NET

Session_Start ハンドラの影響

by WebSurfer 2014年7月26日 17:03

Visual Studio 2010 のテンプレートを使って ASP.NET Web Forms アプリケーション(MVC ではなくて)を新規に作成すると、以下の画像のように、デフォルトで Global.asax ファイルの中に空の Session_Start ハンドラが生成されます。Session State を使わないのであれば、このコードは削除しておいた方がよさそうという話を書きます。

なお、以下の話で Session Cookie という言葉が出てきますが、ブラウザ / サーバー間のセッション ID の授受にクッキーを利用する(即ち、sessionState 要素 の cookieless 属性がデフォルトの UseCookies)ということが前提ですのでご注意ください。

Session_Start ハンドラ

つい先日、MSDN Forum でのやりとりを通じて、Global.asax に Session_Start ハンドラを追加するだけで、サーバーは Session State 情報用のストレージを割り当てて Session Cookie を発行することを知りました。

実は、明示的に Session Sate 情報を使用しない限り(即ち、 Session["Data"] = xxxx; のようなコードを書かない限り)Session Cookie が発行されることはないと思い込んでました。

自分では Session["Data"] = xxxx; のようなコードは書いた覚えはないのに、Fiddler2 などで HTTP ヘッダを見ると Session Cookie がやりとりされていたのが不思議だったのですが、Visual Studio が勝手に追加した Session_Start ハンドラが原因だと知ってやっと謎が解けました。(笑)

調べてみると、そのことは自分が持っている「プログラミング ASP.NET 4」という本の 17.3.1 章に書いてありました。せっかく 9,000 円も出して買った本なのに、読んでなかったです。(汗)

その本によると、"Session_Start ハンドラを使用する場合は、セッション状態は空であっても常に(セッション状態プロバイダーに)保存されます" とのことです。さらに、"Session_Start ハンドラはどうしても必要な場合にのみ細心の注意を払って定義してください" とも書いてありました。

というわけで、Visual Studio のテンプレートで自動生成される空の Session_Start ハンドラは、Session State を使わなければ、例え中身が空であってもアプリケーションに不要な負担をかけるだけなので、削除した方がよさそうです。

自分的には、Session Sate 情報を使用することはあっても、Session_Start ハンドラで何か処置を行う必要があるケースは考え付かないのです。なので、何故テンプレートでこのようなコードが自動的に追加されるのか謎です。


以下は余談ですが、今回の件で Session State に関して調べた情報を書いておきます。

サーバーに接続してくるクライアントごとに Session State をセットアップするのは、ASP.NET の既定の HTTP モジュール SessionStateModule です。

SessionStateModule は、クライアントからの要求を処置する HttpApplication オブジェクトのセットアップ時に呼び出され、一意な セッション ID 文字列の生成または取得と、セッション状態プロバイダ(Session State 情報のストレージ)に対するデータの格納と取得を請け負います。

セッションが開始される時、即ち、要求ヘッダに Session Cookie が含まれない状態でサーバーが初回の要求を受けると、SessionStateModule がセッション ID を生成します。

なお、2 回目の要求以降でも、ブラウザからの要求に Session Cookie が含まれてない場合は、SessionStateModule は要求のたびに新しいセッション ID を生成しますので注意してください。

ちなみに、セッション ID の文字列は、SessionID プロパティ から取得して調べることができます。ブラウザから Session Cookie が送られてこなければ、SessionID の値は要求のたび異なります。

Web アプリケーションの Global.asax に Session_Start ハンドラがあるか、Session State 情報を利用するコード(例えば、Session["Data"] = xxxx;)があると、サーバーは "ASP.NET_SessionId" という名前の Session Cookie を生成し、応答ヘッダに含めてブラウザに送信します。以下のような感じです。

Set-Cookie: ASP.NET_SessionId=d4rbf5nhk1xpo0qouuciwxgy; path=/; HttpOnly

上記の通り期限は設定されてないので、一旦クッキーを受け取るとブラウザを閉じない限りクッキーが消滅することはなく、ユーザーが同じドメイン内で閲覧するときには、ブラウザーはクッキーをサーバーに送信し続けます。

それはセッションがタイムアウト(sessionState 構成要素の timeout 属性に設定した時間が過ぎたことを意味します。デフォルトで 20 分)しても同じです。タイムアウトするとストレージに保存されていたセッションデータは破棄されますが、セッション ID は書き換えられず、同じ ID が使用され続けます。即ち、タイムアウトしてもブラウザとサーバ間のセッションは維持されます。

従って、2 回目以降の要求では毎回 Session Cookie がブラウザからサーバーに送られるので、それに含まれるセッション ID をベースにストレージからデータを取得するなどして HttpSessionState オブジェクトを生成することができます。HttpSessionState オブジェクトには Page の Session プロパティを通じてアクセスできます。

なお、2 回目以降の要求に Session Cookie が送られて来る場合は新しいセッションではないと判断され、Session_Start イベントは発生しないというのがデフォルトの動きになるようです。

なお、上にも書きましたが、Session_Start ハンドラがないもしくは Session State 情報を利用するコードがない場合は、サーバーからは Session Cookie は発行されず、上記とは異なった動きとなりますので注意してください。

以下は上にリンクを張った以外に参考にしたページの URL です。後で探さなくて済むよう貼っておきました。

Tags:

ASP.NET

セッションタイムアウトとログアウト

by WebSurfer 2013年6月29日 20:13

クラッシック ASP の場合は分かりませんが、ASP.NET の場合は、セッションの「タイムアウト」状態とフォーム認証の「ログアウト」状態は違います。

ASP.NET の場合「セッションタイムアウト」というと、MSDN ライブラリの セッション タイムアウトを構成する (IIS 7) によれば、sessionState 構成要素の timeout 属性に設定した時間が過ぎたことを言います。

セッションタイムアウトすると、サーバーに保存されていた SessionState 情報が破棄されます。しかし、それ以外の影響はありません。少なくともフォーム認証には無関係です。

また、SessionState 情報、SessionID、セッション Cookie のいずれからもフォーム認証のチケットに関する情報は取得できません。

なお、SessionState 情報を格納しない場合(Session["Data"] = xxxx; というようなコードが存在しない場合)、サーバーはセッション Cookie を発行しません。(2014/7/26 追記:Global.asax に Session_Start ハンドラを追加すると話が違ってきます。詳しくは、Session_Start ハンドラの影響 を参照ください)

SessionState 情報が格納される場合に限り、SeesionID を含むセッション Cookie が発行されます。なお、セッションタイムアウトしても SessionID は書き換えられず、同じ ID が使用され続けます。即ち、Session["Data"] に保存したデータは破棄されても、ブラウザは要求のたび同じセッション Cookie を送り続けます。

一方、フォーム認証の「ログアウト」状態とは認証チケットを持っていない、もしくは認証チケットは持っていても期限切れという状態です。セッションがタイムアウトしていても認証チケットは有効と言うことは当然あります。その逆もあります。

従って、フォーム認証チケットの有無もしくは期限切れと、セッションタイムアウトとは関係なく、セッションの「タイムアウト」状態 = フォーム認証の「ログアウト」状態にはならないです。

なお、Windows 認証、統合 Windows 認証は、フォーム認証とは全くメカニズムが異なっていて、セッションもクッキーも関係ないです。

Tags:

Authentication

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2017年4月  >>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

View posts in large calendar