5

この投稿はもともと問題を見つけようとしていたもので、web.config の問題だと思いました。また、マスターページのコードビハインドにあると思いました。ここにあるすべてのテキストは、問題を発見するプロセスの一部です。最新の更新については、一番下までスクロールしてください。

私の Web サイトでは、ユーザーがテキスト ボックスにコードを入力できます。認識されたコードが入力されると、ページが更新され、そのユーザーにウェルカム メッセージが表示されます。それ以外の場合は、エラー メッセージが表示されます。名前を取得できるように、手動で入力したコードをセッションに入れています。セッションをページ間にとどめることはできません。私のコードはすべてマスター ページの vb ページにあり、何が間違っているのかわかりません。

  • 確認するように言われましたEnableSessionState="true"が、マスターページでは機能しません。
  • IIS の設定を確認するように言われましたが、アクセス許可がないため確認できません。
  • 試みSessionState cookieless="UseUri"たところ、終わりのないリダイレクトループが作成されました。
  • 関数をデバッグしましたが、値を返します。
  • コードを入力するとテキストボックスが消え、ウェルカムメッセージにユーザーの姓と名が表示されるので、うまくいくことがわかります。
  • Session.Abandonサイトのどこにもコードがないことを確認しました。
  • Watchページ上の のすべてのインスタンスにを追加Session("IB")し、テキスト ボックスにコードを入力すると正しく入力されます。次に、リンクをクリックして別のページに移動すると、デバッガーが の最初の行で停止しPage_LoadDim ib As String = CType(Session.Item("IB"), String)監視しているすべての IB 変数がすぐに に変わりますNothing

マスター ページのコード ビハインドは次のとおりです。

Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.OleDb
Partial Class MasterPage
  Inherits System.Web.UI.MasterPage
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
      Dim BAccount As String = CType(Session("BAccount"), String)
       If Not IsPostBack Then
        If Session("BAccount") Is Nothing Then
            'no such value in session state, show textbox for IB to enter code
            IBText.Visible = True
            IBTextBox.Visible = True
            IBTextBoxButton.Visible = True
            lbNotIB.Visible = False
        Else
            'call function
            GetSessionValues(BAccount)
        End If
    End If
End Sub
Protected Function GetSessionValues(ByVal Code As String) As Boolean
    Dim FirstName As String = CType(Session("First_Name"), String)
    Dim LastName As String = CType(Session("Last_Name"), String)
    Dim Name As String = CType(Session("Name"), String)
    If GetAccountName(FirstName, LastName) Then
        'hide textbox
        IBText.Visible = False
        IBTextBox.Visible = False
        IBTextBoxButton.Visible = False
        'show welcome message to user if IB code exists in database
        lblIB.Visible = True
        lblIB.Text = "Welcome, " + Session("First_Name") + " " + Session("Last_Name") + "."
        lbNotIB.Visible = True
        lbNotIB.Text = "Not " + Session("First_Name") + " " + Session("Last_Name") + "?"
        Return True
    ElseIf GetBackUpAccountName(Name) Then
        'hide textbox
        IBText.Visible = False
        IBTextBox.Visible = False
        IBTextBoxButton.Visible = False
        'show welcome message to user if IB code exists in database
        lblIB.Visible = True
        lblIB.Text = "Welcome, " + Session("Name") + "."
        lbNotIB.Visible = True
        lbNotIB.Text = "Not " + Session("Name") + "?"
        Return True
    Else
        'IB code not found
        'shows error message in red
        lblIB.ForeColor = Drawing.Color.Red
        lblIB.Text = "Account not found, please try again."
        Return False
    End If
End Function
Private Function GetAccountName(ByRef FirstName As String, ByRef LastName As String) As Boolean
    'declare variable
    Dim BAccount As String = CType(Session("BAccount"), String)
    'sql statement for baccount information
    Dim sql As String = "SELECT BAccount, First_Name, Last_Name FROM IB INNER JOIN IB_BUISNESS_INFORMATION ON (IB.IB_ID = IB_BUISNESS_INFORMATION.IB_ID) WHERE BAccount = @BAccount"
    Using conn As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("IBConnectionString").ConnectionString)
        Using cmd As New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@BAccount", SqlDbType.VarChar)
            cmd.Parameters("@BAccount").Value = IBTextBox.Text
            If IBTextBox.Text Is Nothing Then
                cmd.Parameters("@BAccount").Value = DBNull.Value
            Else
                cmd.Parameters("@BAccount").Value = IBTextBox.Text
            End If
            conn.Open()
            Using rdr As SqlDataReader = cmd.ExecuteReader
                If (rdr.Read) Then
                    FirstName = rdr("First_Name").ToString()
                    LastName = rdr("Last_Name").ToString()
                    Return True
                Else
                    Return False
                End If
            End Using
            conn.Close()
        End Using
    End Using
End Function
Private Function GetBackUpAccountName(ByRef Name As String) As Boolean
    'declare variable
    Dim BAccount As String = CType(Session("BAccount"), String)
    'sql statement for baccount information in case BAccount is not found, search here next
    Dim backupsql As String = "SELECT BAccount, Name FROM brokermaster WHERE BAccount = ?"
    Using conn As New OleDbConnection(System.Configuration.ConfigurationManager.ConnectionStrings("BackUpConnectionString").ConnectionString)
        Using cmd As New OleDbCommand(backupsql, conn)
            cmd.Parameters.AddWithValue("?", SqlDbType.VarChar)
            cmd.Parameters("?").Value = IBTextBox.Text
            If IBTextBox.Text Is Nothing Then
                cmd.Parameters("?").Value = DBNull.Value
            Else
                cmd.Parameters("?").Value = IBTextBox.Text
            End If
            conn.Open()
            Using backuprdr As OleDbDataReader = cmd.ExecuteReader
                If (backuprdr.Read) Then
                    Name = backuprdr("Name").ToString()
                    Return True
                Else
                    Return False
                End If
            End Using
            conn.Close()
        End Using
    End Using
End Function
Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
    'declare variables
    Dim FirstName As String = CType(Session("First_Name"), String)
    Dim LastName As String = CType(Session("Last_Name"), String)
    Dim Name As String = CType(Session("Name"), String)
    If (Not GetSessionValues(args.Value)) Then
        args.IsValid = False
    Else
        args.IsValid = True
    End If
    If GetAccountName(FirstName, LastName) Then
        'set session variables
        Session("First_Name") = FirstName
        Session("Last_Name") = LastName
        'hide textbox
        IBText.Visible = False
        IBTextBox.Visible = False
        IBTextBoxButton.Visible = False
        args.IsValid = True
        'show welcome message to user if IB code exists in database
        lblIB.Visible = True
        lblIB.Text = "Welcome, " + Session("First_Name") + " " + Session("Last_Name") + "."
    ElseIf GetBackUpAccountName(Name) Then
        'set session variables
        Session("Name") = Name
        'hide textbox
        IBText.Visible = False
        IBTextBox.Visible = False
        IBTextBoxButton.Visible = False
        args.IsValid = True
        'show welcome message to user if IB code exists in database
        lblIB.Visible = True
        lblIB.Text = "Welcome, " + Session("Name") + "."
    Else
        'IB code not found
        args.IsValid = False
        'shows error message in red
        lblIB.ForeColor = Drawing.Color.Red
        lblIB.Text = "Account not found, please try again."
    End If
End Sub
Protected Sub IBTextBoxButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles IBTextBoxButton.Click
    If Page.IsValid Then
        'declare variables
        Dim LSD As String = CType(Session("LSD"), String)
        Dim LSC As String = CType(Session("LSC"), String)
        Dim BAccount As String = CType(Session("BAccount"), String)
        Session("BAccount") = IBTextBox.Text
        'add session variable
        If GetCompanyName(LSD) Then
            Session("LSD") = LSD
        End If
        'add session variable
        If GetWebsite(LSC) Then
            Session("LSC") = LSC
        End If
    End If
End Sub
Private Function GetCompanyName(ByRef LSD As String) As Boolean
    'declare variable
    Dim BAccount As String = CType(Session("BAccount"), String)
    'sql statement to get company information
    Dim sql As String = "SELECT Company_Name, BAccount FROM IB_CONTACT_INFORMATION INNER JOIN IB_BUISNESS_INFORMATION ON (IB_CONTACT_INFORMATION.IB_ID = IB_BUISNESS_INFORMATION.IB_ID) WHERE BAccount = @BAccount"
    Using conn As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("IBConnectionString").ConnectionString)
        Using cmd As New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@BAccount", SqlDbType.VarChar)
            cmd.Parameters("@BAccount").Value = IBTextBox.Text
            If IBTextBox.Text Is Nothing Then
                cmd.Parameters("@BAccount").Value = DBNull.Value
            Else
                cmd.Parameters("@BAccount").Value = IBTextBox.Text
            End If
            conn.Open()
            Using rdr As SqlDataReader = cmd.ExecuteReader
                If (rdr.Read) Then
                    LSD = rdr("Company_Name").ToString()
                    Return True
                Else
                    Return False
                End If
            End Using
            conn.Close()
        End Using
    End Using
End Function
Private Function GetWebsite(ByRef LSC As String) As Boolean
    'declare variable
    Dim BAccount As String = CType(Session("BAccount"), String)
    'sql statement for website information
    Dim sql As String = "SELECT TOP 1 WebSites, BAccount FROM IB_WEBSITES INNER JOIN IB_BUISNESS_INFORMATION ON (IB_WEBSITES.IB_ID = IB_BUISNESS_INFORMATION.IB_ID) WHERE BAccount = @BAccount"
    Using conn As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("IBConnectionString").ConnectionString)
        Using cmd As New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@BAccount", SqlDbType.VarChar)
            cmd.Parameters("@BAccount").Value = IBTextBox.Text
            If IBTextBox.Text Is Nothing Then
                cmd.Parameters("@BAccount").Value = DBNull.Value
            Else
                cmd.Parameters("@BAccount").Value = IBTextBox.Text
            End If
            conn.Open()
            Using rdr As SqlDataReader = cmd.ExecuteReader
                If (rdr.Read) Then
                    LSC = rdr("WebSites").ToString()
                    Return True
                Else
                    Return False
                End If
            End Using
            conn.Close()
        End Using
    End Using
End Function
Protected Sub lbNotIB_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbNotIB.Click
    'if user is not IB that currently holds session, this will destroy the session and allow them to enter different code
    Session.Abandon()
    Response.Redirect(Request.RawUrl)
End Sub

クラス終了

aspx:

<asp:Label ID="IBText" runat="server" Text="Enter your IB code here:"></asp:Label>
  <asp:TextBox ID="IBTextBox" runat="server"></asp:TextBox>
  <asp:Button ID="IBTextBoxButton" runat="server" Text="Submit" />
  <asp:CustomValidator ID="CustomValidator1" runat="server"
  ControlToValidate="IBTextBox" ForeColor="Red"
  OnServerValidate="CustomValidator1_ServerValidate"></asp:CustomValidator>
<asp:Label ID="lblIB" runat="server" Text=""></asp:Label>

web.config:

<sessionState mode="InProc" cookieless="false" timeout="20" sqlConnectionString="Data Source=***;Initial Catalog=***;Persist Security Info=True;User ID=***;Password=***">
</sessionState>

更新: ハァッ! ついに手に入れました!したがって、ここには2つの問題があります。<httpModules>私は私の中に設定していませんでしたweb.config。追加する必要がありました:

<httpModules>
   <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
</httpModules>

参照

問題は、これらの 2 つのデータベースから情報を取得しているのに、ファイルのセクションにSessions1 つのデータベースしかリストされていないことです。2番目を追加しようとしましたが、エラーが発生しました。<sessionState>web.config<sessionState>

2 番目のデータベースを含める方法はありますか? そうしないと、セッションの半分がウェブサイト全体に残り、半分が消えてしまいます。ちなみに、私はデータベースの作成とは何の関係もありませんでした。これはすべて、私の時間よりもずっと前に行われました。

これを web.config で試しましたが、うまくいきません:

<sessionState mode="InProc" 
              cookieless="false" 
              timeout="20" 
              sqlConnectionString="IBConnectionString, BackUpConnectionString">
</sessionState>

さらに別の更新: asp.net フォーラムのユーザーから提案された、私が試した別のことを次に示します。<sessionState>これにより 500 内部サーバー エラーも生成されたので、 のインスタンスを 2 つ持つことは許可されていないと思います。

<sessionState mode="SQLServer"
              cookieless="false"
              timeout="20"
              sqlConnectionString="IBConnectionString">
</sessionState>
<sessionState mode="SQLServer"
              cookieless="false"
              timeout="20"
              sqlConnectionString="BackUpConnectionString">
</sessionState>

詳細: sessionState変更され、サイトは以前と同じように動作しConnectionStringます。これは、2 番目のデータベースがセッションを失うという問題とは何の関係もありません。それはコードの背後にあるものでなければなりません.web.configで他に何が問題なのか考えられません。

<sessionState mode="InProc" timeout="20"></sessionState>

また、セッション変数がまだそこにあることもわかりました。バックアップ データベース接続に接続されている場合、ユーザーの情報は表示されません。


熟考とフラストレーションの末、私は上司に、データベースを組み合わせるだけでどれほど難しいかを尋ねました。バックアップ アカウント データベースには 2400 を超えるレコードがありますが、他に選択肢はありません。すぐに解決策が得られるとは思っていません。これですでに 1 か月を無駄にしています。助けてくれてありがとう。

何かを見つけたら、戻ってこの投稿を編集します!

4

3 に答える 3

2

まず、ページの Init 部分にあるコードを削除します。不要です。

次に、コードの一部でセッションの IB 値を True に設定しているのはなぜですか? 口座番号の上書きです。両方変えて..

Session("IB") = True

Session("IB") = args.Value

または、その時点でセッションを台無しにしないでください.IBTextBoxButton_Click サブルーチンから既に設定されているはずです。

于 2012-03-26T19:57:10.963 に答える
1

web.configでセッション状態が有効になっていることを確認してください。「StateServer」または「SQLServer」に設定されている場合は、テスト目的で「InProc」に変更して、外部の障害のある依存関係を除外します。

<sessionState mode="InProc" />
于 2012-03-26T20:01:20.783 に答える
1

また、過去にセッションを「食べた」ように見える例外がスローされるのを見てきました。問題を引き起こしている可能性のある try/catch ブロックを探します。

通常、コードを 1 ステップ実行すると問題が表示されますが、そうでない場合は、「私はここにいます」というメッセージをコードに散りばめることで役立つことがあります。

どの行 (またはその近く) が問題を引き起こしているように見えるかを確認できると、ひらめきを引き起こすのに役立つ場合があると考えられています。

たとえば、おおよその行番号とともにセッション変数の状態をダンプし、それを Web ページのいくつかの場所に出力するだけです。

また、デバッグするコードの量を絞り込むようにしてください。

問題を小さなコード セットに切り分けることができれば、多くの場合、問題の特定に役立ちます。

**編集**どうやら私はただスキャンしていたようです。あなたの投稿を実際に読んだところ、問題の原因となっている行を特定したことがわかりました。行に問題はありませんが、何らかの理由で別のセッション変数名を使用してみます。参考になるかわかりませんが、簡単に試してみてください。おそらく、より長いセッション変数名を使用してください。デバッガーを目の前で開かないと、頭のてっぺんから他に何をチェックすればよいかわかりません。

于 2012-03-28T17:51:08.447 に答える