- - PR -
ASP.NET セッション変数
«前のページへ
1|2|3|4
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-09-11 12:05
このままやり取りを続けても堂々巡りになりそうな気がします。現象の再現する最低限のコード、およびUIの操作パターンを示す事は出来ませんか?
複数ユーザーで操作を行ったときにのみ発生するのであれば、他の方の言葉にもあるように「スレッドセーフに作られていない箇所が存在する」可能性が濃厚です。後は詳細なログを出力(随所でSessionIDとSessionの内容を保存すれば十分でしょう)して解析し、Session変数の変化する箇所を特定するぐらいしか、解決方法を思いつけません。 私もSession変数の内容が勝手に変化するとは信じていません。もし本当にSession変数の内容が勝手に変化していしまうとしたら、それは.NET Frameworkの持つ致命的なバグと言えるでしょう。 _________________ 甕星 <mikahosi@abox9.so-net.ne.jp> http://blogs.msmvp.jp/mikahosi/ | ||||
|
投稿日時: 2005-09-11 18:04
長くなってしまいますが、該当部分のソースです。
(細かいエラー処理やメッセージ表示部分などは省略しました。) ●前提 ユーザはログイン画面でユーザID、営業所コード、パスワードを入力する。 ユーザはユーザID+営業所コードで一意に識別される ●ログイン画面 Imports System.Data Imports System.Data.SqlClient Public Class Login Inherits System.Web.UI.Page ・ ・ '<ログイン>ボタン押下 Private Sub cmdLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLogin.Click Dim DBConnect As New SqlConnection() Dim DBReader As SqlDataReader Dim strUName As String '担当者氏名 Dim strEigyo As String '営業所名 Dim strGrantCD As String '権限コード Try 'データベースオープン If funDBOpen(DBConnect) = False Then Exit Sub End If 'パスワードチェックとセッション変数に設定する情報を取得 If funLoginCheck(txtUserID.Text, txtEigyoCD.Text, txtPassword.Text, strUName, strEigyo, strGrantCD, DBReader, DBConnect) = False Then Exit Sub End If 'ユーザ情報をセッション変数に設定 Call subSetSession(txtUserID.Text, strUName, txtEigyoCD.Text, strGrantCD) '一覧画面へ遷移 Call Response.Redirect("<遷移先URL>", False) Catch 'エラー処理 Finally ' 'データベースクローズ Call subDBClose(DBConnect) End Try End Sub Function funLoginCheck(ByVal strUserID As String, _ ByVal strEigyoCD As String, _ ByVal strPassword As String, _ ByRef strUName As String, _ ByRef strEigyo As String, _ ByRef strGrantCD As String, _ ByRef DBReader As SqlDataReader, _ ByRef DBConnect As SqlConnection) As Boolean funLoginCheck = False Dim strSql As String Try 'ユーザ名、パスワードを取得 strSql = "SELECT <ユーザ名>, <パスワード>" strSql &= " FROM <ユーザテーブル>" strSql &= " WHERE <ユーザID> = " & strUserID strSql &= " AND <営業所ID> = " & strEigyoCD 'レコードオープン If funRecOpen(strSql, DBReader, DBConnect) = False Then Exit Function End If '存在確認 If DBReader.Read() = False Then Exit Function Else 'パスワードチェック If DBReader("<パスワード>").ToString <> strPassword Then Exit Function Else 'ユーザ名 strUName = DBReader("<ユーザ名>").ToString 'レコードクローズ Call subRecClose(DBReader) '営業所名を取得 strSql = "SELECT <営業所名>" strSql &= " FROM <営業所テーブル>" strSql &= " WHERE <営業所ID> = " & strEigyoCD 'レコードオープン If funRecOpen(strSql, DBReader, DBConnect) = False Then Exit Function End If If DBReader.Read() = False Then Exit Function Else '営業所名 strEigyo = DBReader("<営業所名>").ToString End If 'レコードクローズ Call subRecClose(DBReader) 'ユーザ権限を取得 strSql = "SELECT <ユーザ権限>" strSql &= " FROM <ユーザ権限テーブル>" strSql &= " WHERE <ユーザID> = " & strUserID strSql &= " AND <営業所ID> = " & strEigyoCD 'レコードオープン If funRecOpen(strSql, DBReader, DBConnect) = False Then Exit Function End If If DBReader.Read() = False Then Exit Function Else 'ユーザ権限 strGrantCD = DBReader("<ユーザ権限>").ToString End If End If End If funLoginCheck = True Catch 'エラー処理 Finally 'レコードクローズ Call subRecClose(DBReader) End Try End Function Sub subSetSession(ByVal strUserID As String, _ ByVal strUName As String, _ ByVal strEigyoCD As String, _ ByVal strEigyo As String, _ ByVal strGrantCD As String) Session("<ユーザID>") = strUserID Session("<ユーザ名>") = strUName Session("<営業所ID>") = strEigyoCD Session("<営業所名>") = strEigyo Session("<ユーザ権限>") = strGrantCD End Sub End Class ●メニュー画面 Imports System.Data Imports System.Data.SqlClient Public Class Menu Inherits System.Web.UI.Page ・ ・ Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' ページを初期化する ユーザー コードをここに挿入します。 Dim DBConnect As New SqlConnection() Try If Not IsPostBack Then 'データベースオープン If funDBOpen(DBConnect) = False Then Exit Sub End If '情報取得 If funGetInfo(DBConnect) = False Then Exit Sub End If 'ログインユーザを表示 txtTanto.Text = Session("<ユーザ名>").ToString txtEigyo.Text = Session("<営業所名>").ToString End If Catch 'エラー処理 Finally 'データベースクローズ Call subDBClose(DBConnect) End Try End Sub ・ ・ End Class ●Module Imports System.Data Imports System.Data.SqlClient Module Module1 Function funDBOpen(ByRef DBConnect As SqlConnection) As Boolean Dim strCnn As String funDBOpen = False Try '接続文字列をWeb.configから取得 strCnn = ConfigurationSettings.AppSettings("DBConnectionString") 'DB接続 DBConnect.ConnectionString = strCnn DBConnect.Open() funDBOpen = True Catch 'エラー処理 End Try End Function Function funRecOpen(ByVal strSql As String, ByRef DBReader As SqlDataReader, _ ByRef DBConnect As SqlConnection) As Boolean funRecOpen = False 'コマンドオブジェクト作成 Dim DbCommand As New SqlCommand() Try If (DBConnect Is Nothing) Or (strSql = "") Then DBReader.Close() DBReader = Nothing Exit Function End If DbCommand.Connection = DBConnect DbCommand.CommandText = strSql DBReader = DbCommand.ExecuteReader() funRecOpen = True Catch 'エラー処理 Finally DbCommand = Nothing End Try End Function Sub subRecClose(ByRef DBReader As SqlDataReader) Try If Not DBReader Is Nothing Then DBReader.Close() DBReader = Nothing End If Catch 'エラー処理 End Try End Sub Sub subDBClose(ByRef DBConnect As SqlConnection) Try If Not DBConnect Is Nothing Then 'DB切断 DBConnect.Close() DBConnect.Dispose() DBConnect = Nothing End If Catch 'エラー処理 End Try End Sub Function funGetInfo(ByRef DBConnect As SqlConnection) As Boolean Dim DBreader As SqlDataReader Dim strSQL As String funGetInfo = False Try strSQL = "SELECT * FROM <テーブル名>" strSQL &= " WHERE <ユーザID> = " & HttpContext.Current.Session("<ユーザID>").ToString strSQL &= " AND <営業所ID> = " & HttpContext.Current.Session("<営業所ID>").ToString If funRecOpen(strSQL, DBreader, DBConnect) = False Then Exit Function End If If DBreader.Read() = True Then ・ ・ End If funGetInfo = True Catch 'エラー処理 Finally Call subRecClose(DBreader) End Try End Function End Module ●現象発生の操作 ログイン後、しばらくは本人のユーザ名・営業所名が表示される。 しばらく動かした後、上記のメニュー画面に戻った際に、他人の ユーザ名・営業所名が表示される。 以上を踏まえて、再度私の疑問点を挙げさせて頂くと、 「メニュー画面の情報取得部分が静的変数によって他人の結果が 返ってきたとしても、その直後に txtTanto.Text = Session("<ユーザ名>").ToString としている部分で他人のユーザ名が表示されるのはなぜでしょうか?」 という事です。 自分なりに考えてみると、 ・メニュー画面に戻ってくる前に、何かしらの理由によって 「Session("<ユーザ名>")」が他人のものに上書きされていた。 かと思うのですが、この「Session("<ユーザ名>")」を使用するのは 上記メニュー画面を含めて2箇所、かつ使い方は同じでテキストボックスに セットしているだけのため、上書きされる理由が分からないのです。 (「Session("<ユーザ名>")」に値をセットするのはログイン画面の1箇所。) (余談) 最初の書込みでは情報が少なすぎて、皆さんの考えるモトがなかったのですね。 おおいに反省しております。 | ||||
|
投稿日時: 2005-09-11 22:25
IEで CTRL+N を押すと、別のIEが起動します。
一方でAでログインし、もう一方でBでログインすれば現象が出ると思います。 これは、二つのIEがセッションを共有してしまうからです。 しかし、別のパソコンならセッションを共有するのは有り得ないはずです。 | ||||
|
投稿日時: 2005-09-12 21:21
ん〜、応える人の多くは考えることが楽しいんだから、考えるネタがたくさんあるのは、それはそれでおもしろいんですよ。 ただ、後出しジャンケンをされると嫌な気がするし、それが文字にでちゃうとあなたも嫌な思いをするし、問題解決もズルズル後ろへ行っちゃう。それだけのことです。 _________________ |
«前のページへ
1|2|3|4