質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

2回答

11347閲覧

セッション読み込み完了時にログインチェックを行いたい

syogakusya

総合スコア67

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

1クリップ

投稿2016/07/05 15:02

編集2016/07/06 03:38

###前提・実現したいこと
ASP.NETで、セッション読み込み完了時に共通処理としてログインチェックを行いたいです。
グローバルアプリケーションクラス内のApplication_BeginRequestイベントで
処理を行ってみたのですが、以下のような例外が出ました。

このコンテキストでセッション状態は利用できません。

MSDNに掲載されているページのライフサイクルの概要等を参照した結果、
Application_BeginRequestイベントが発生する段階では
セッション情報が取得されていないらしいということが分かったのですが、
セッション取得完了直後に発生するイベントが分かるような記事が見つからずに困っています。
以下にソースコードを記述します。

###該当のソースコード

C#

1 2Global.asax.cs 3 4protected void Application_BeginRequest(object sender, EventArgs e) 5{ 6 // ログインIDがセッションから取得できず、ログインが必要なページなら 7 if (Session["USER_ID"] == null && Request.Url != ...) 8 { 9 // タイムアウト画面へ遷移する処理 10 ... 11 } 12}

###試したこと
ネット上の記事を参考にSession_Startイベントに処理を記述してみました。
リクエストのセッションが取得できなかった場合にはセッションが新しく作成されるため、
そこでこのイベントが起きるということだと思います。
(目的を満たせなかったため、詳しいことを調べてはいません。)
しかし、このイベントではタイムアウトしか検知することが出来ないため、
遷移後に戻るボタンを使用したりして再び元の画面で操作を行った場合はダメでした。
そもそもタイムアウトのハンドリングの記事だったと思うので、改めて考えると目的がずれていました。

###備考
同様の課題についてマスターページのInitイベントに処理を記述する手法で解決した前例を
ネット上で発見し、少なくとも目的は満たせそうなため、一度はそれで満足しかけたのですが、
その方法だとコンテンツページのInitイベントで行いたい処理がある場合には機能しないため、
本質的な解決にはならないのではないかと考え直しました。
熟考の末、論理的な側面から考えても、ログインチェックを行いたいタイミングは、
ページの初期化時ではなくセッションが取得できた直後だと思い、よりよい方法を知りたいと思いました。

追記:マスターページのInitイベントはコンテンツページのInitイベントより先に発生するため、コンテンツページのInitイベントで行う処理があったとしても影響はありませんでした。しかし、コンテンツページのPreInitイベントはマスターページのInitより先に起きるようです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Application_BeginRequest イベントにてページリクエストのたびにログインチェックを行いたいというなら以下のような感じですかねえ。

1.ユーザーがログイン画面にてユーザーIDとパスワードを入力して認証を行った時にセッションID(Session.SessionID) と ユーザーID(Session.Contents["USER_ID"]) をセットにしてApplication.Contentsに保存する。

C#

1Application.Contents[Session.SessionID] = Session.Contents["USER_ID"];

2.Application_BeginRequest イベントにて Request.Cookies["ASP.NET_SessionId"].value に格納されているセッションIDを取得する。
3.取得したセッションIDをキーにしてApplication.Contentsを読み込みユーザーIDを取得する。
4.取得したユーザーIDでログインチェックを行う。

C#

1String sessionid = Request.Cookies["ASP.NET_SessionId"].value; 2String userid = Application.Contents[sessionid]; 3if (userid == ... ){

とりあえずApplication.Contentsに保存していますが、できればデータベースとかの方が望ましいでしょう。

ただ、この方法だと後々行き詰るような気がします。
ページリクエストのたびにログインチェックするのもパフォーマンス的にどうなんだろうと思いますし。

私としてはASP.NETのフォーム認証機能を使うことをおすすめします。

投稿2016/07/11 07:55

編集2016/07/11 07:57
twck

総合スコア314

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

Asp.Net Global.asax内イベント発生する順序を参考にされては

Application_Start


Application_BeginRequest (HTTPリクエストハンドラでのリクエスト処理開始前)

Application_AuthenticateRequest (認証準備完了後)

Application_AuthorizeRequest (ユーザ認証完了後)

Application_ResolveRequestCache (キャッシュからの後続の要求を処理するために使用する応答をキャッシング モジュールで格納できる)
ここまでセッションを利用できません。

Session_Start (セッション開始、この前のイベント内セッションを利用できません。)

Application_AcquireRequestState (リクエストに関連した状態(セッション等)を取得時

Application_PreRequestHandlerExecute (HTTPハンドラによるページ実行直前)

Application_PostRequestHandlerExecute (HTTPハンドラによるページ実行終了後)

Application_ReleaseRequestState (実行処理の終了後)
ここからセッションを利用できません。

Application_UpdateRequestCache (出力キャッシュ更新後)

Application_EndRequest (HTTPリクエスト処理完了後)

Application_PreSendRequestHandlers (HTTPヘッダ情報送信前)
筆者の環境ではこのイベント入りません

Application_PreSendRequestContent (HTTPコンテンツ情報送信前)

投稿2016/07/05 19:12

dojikko

総合スコア3939

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syogakusya

2016/07/06 03:18 編集

マスターページのInitイベントはコンテンツページのInitイベントより先に起きるのですね。知りませんでした。 ご提示頂いた情報を参考にAcquireRequestStateイベントについて少し調べ、実際に使ってみたのですが、一度のリクエストで複数回イベントが起きてしまいます。 具体的には、必ず一度はページイベントより前に起きるのですが、2回目や3回目の同イベントがページの読み込みイベント終了後に起きたりします。 この現象について何か解決のヒントはございませんか。 マスターページのInitイベントも一応試してみましたが、こちらでは正常に動作しました。 可能ならページレベルではなくアプリレベルのイベントで処理をしたいという思いです。 引き続きよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問