VB.NET - Session isn't working correctly - Asked By Jamie Grinnell on 22-Mar-12 03:57 PM

I was pretty sure that I am setting the session variable right, but it is not staying when I move from page to page in my web site. The functions work and get the names from the database, they also display the text that I told it to display. I just can't get the text to stay from page to page. In my page_load when debugging, Session("IB") is Nothing. I don't understand what I am doing wrong here. This code is all on the master page.

I have tried adding EnableSessionState = "true" to the page directive, but because the code is on the master page, it shows an error saying that EnableSessionState isn't valid on a master page. For some reason, the function GetSessionValues() in the Page_Load is never called, it just keeps coming back with Session("IB") Is nothing so then it goes to that part of the code.  Help is greatly appreciated. 


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) Handles Me.Load
  Dim ib As String = Session("IB")
  If Not IsPostBack Then
  If Request.QueryString("IB") IsNot Nothing Then
  ib = Request.QueryString("IB")
  Session("IB") = True
  End If
  If Session("IB") Is Nothing Then
  'show textbox
  IBText.Visible = True
  IBTextBox.Visible = True
  IBTextBoxButton.Visible = True
  Else
  'call function
  GetSessionValues(ib)
  End If
  End If
  End Sub
  Protected Function GetSessionValues(ByVal Code As String) As Boolean
  Dim FirstName As String = Session("First_Name")
  Dim LastName As String = Session("Last_Name")
  Dim Name As String = Session("Name")
  If GetAccountName(Code, 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") + "."
  Return True
  ElseIf GetBackUpAccountName(Code, 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") + "."
  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(ByVal BAccount As String, ByRef FirstName As String, ByRef LastName As String) As Boolean
  '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(ByVal BAccount As String, ByRef Name As String) As Boolean
  '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 = String.Empty
  Dim LastName As String = String.Empty
  Dim Name As String = String.Empty
  If (Not GetSessionValues(args.Value)) Then
  args.IsValid = False
  Else
  args.IsValid = True
  End If
  If GetAccountName(args.Value, FirstName, LastName) Then
  'set session variables
  Session("First_Name") = FirstName
  Session("Last_Name") = LastName
  Session("IB") = True
  '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(args.Value, Name) = True Then
  'set session variables
  Session("Name") = Name
  Session("IB") = True
  '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 = String.Empty
  Dim LSC As String = String.Empty
  Session("IB") = IBTextBox.Text
  Dim IB As String = Session("IB")
  'add session variable
  If GetCompanyName(LSD) Then
  Session("LSD") = LSD
  Else
  'no data found
  End If
  'add session variable
  If GetWebsite(LSC) Then
  Session("LSC") = LSC
  Else
  'no data found
  End If
  End If
  End Sub
  Private Function GetCompanyName(ByRef LSD As String) As Boolean
  'declare variable
  Dim BAccount As String = Session("IB")
  '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 = Session("IB")
  '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
End Class
Somesh Yadav replied to Jamie Grinnell on 26-Mar-12 01:28 AM

Setting EnableSessionState=true doesn't really achieve much, it's on application-wide by default. To ensure your IIS7 configuration is correct, you can try executing the following
http://technet.microsoft.com/en-us/library/cc725624%28WS.10%29.aspx:

appcmd set config /commit:WEBROOT /section:sessionState /mode:InProc

If you're seeing a new SessionID on every page, it could simply be that your client isn't storing/forwarding the session cookie (possibly because of security restrictions on the browser). First verify that you are indeed presenting the session cookie, and that all requests are served from the same domain.

To verify that it's not a cookie issue, you can switch session state to use cookieless mode to see if the correct session is loaded on subsequent requests:

<sessionState cookieless="UseUri" />
Jamie Grinnell replied to Somesh Yadav on 05-Apr-12 10:57 AM
I tried setting sessionstate cookieless="useuri" and the page times out and says there are too many redirect loops. I have  no idea what that means, there are no loops when I have cookieless set to false. Also, I can't access IIS settings so I won't be able to try that one. I do have another site in process where the session works, if that helps.

UPDATE: I was able to figure out the problem and one of the fixes. I needed to add this to my web.config:
<httpModules>
   <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
</httpModules> But this only allows sessions to be set from one database. I need to connect to another database for user information as well. How do I use sessionState with 2 databases? I can't find anything helpful online at all.
Erik Little replied to Jamie Grinnell on 05-Apr-12 11:54 PM
There are three different types of session state storage.
1.) Is the inprocess mode and this is default. You do not have to set up anything to get this one to work.
2.) Server mode. the one that you use to save session to a database
3.) A custom one, and i can assure you that you do not want any of that action right now.

It looks as if you're trying to store the session state in the query string and retrieve it in another fashion. If you're not sure which session state to use then you only need to use the in-process one , which you do not have to do anything at all, this one is set up and ready to go.

  Me.Session().Add("MySessionName", "My Session Value")
        If IsPostBack Then


            Dim str As String
            str = CType(Session("MySessionName"), String)


        End If
Jamie Grinnell replied to Erik Little on 09-Apr-12 10:37 AM
I am using the InProc sessionState mode. In my last update, I wrote what the problem was and all that I need to know now is if I can use another sessionState for session information that is coming from a 2nd database. I have <sessionState> set up in the web.config for one database, but I have another one that I need a <sessionState> set up for and the web.config won't let me use it.