2012-03-26 6 views
5

Это сообщение изначально пыталось найти проблему, которая, как я думал, была проблемой web.config. Я также думал, что это что-то в коде позади моей главной страницы. Весь текст здесь является частью процесса выяснения проблемы, прокрутите вниз до самых последних обновлений.Использование 2 баз данных для информации о сеансе в ASP.NET

Мой сайт позволяет пользователям вводить код в текстовое поле. Если введен распознанный код, страница обновится и отобразит приветственное сообщение этому пользователю, в противном случае появится сообщение об ошибке. Я помещаю их введенный вручную код в сеанс, чтобы их имя можно было отключить. Я не могу заставить сеанс оставаться между страницами. Весь мой код находится на странице главной страницы главной страницы, и я не знаю, что я делаю неправильно.

  • Мне сказали, чтобы убедиться, что EnableSessionState="true", но это не работает на главных страницах.
  • Мне сказали проверить настройки IIS, но я не могу, потому что у меня нет прав на него.
  • Пробовал SessionState cookieless="UseUri" и каким-то образом создал бесконечный цикл переадресации.
  • Я отлаживал функции, и они возвращают значения.
  • Текстовое поле Уходит, когда я ввожу код, и приветственное сообщение отображается с именем и фамилией пользователя, поэтому я знаю, что это работает.
  • Я проверил, чтобы не было кода Session.Abandon в любом месте сайта.
  • Я добавил Watch всем экземплярам Session("IB") на странице, и они заполнены правильно, когда я ввожу код в текстовое поле. Затем, когда я нажимаю на ссылку, чтобы перейти на другую страницу, отладчик останавливается в первой строке в моих Page_Load, Dim 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 

End Class

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> 

UPDATE: Хах! Я, наконец, понял! Таким образом, здесь есть две проблемы. У меня не было <httpModules>, установленного в моем web.config. мне нужно добавить:

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

Reference

Теперь проблема заключается в том, что у меня есть информация тянет из 2-х баз данных для этих Sessions, но только одна база данных перечислены в разделе <sessionState> моего web.config файла. Я попытался добавить второй <sessionState>, но он выбросил ошибку.

Есть ли способ включить вторую базу данных? Если я этого не сделаю, половина моих сеансов останется на веб-сайте, а половина исчезнет. Кстати, я не имел никакого отношения к созданию базы данных, все это было сделано до моего времени.

Я попробовал это в web.config, но он также не работает:

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

Еще одно обновление: Вот еще одна вещь, которую я попробовал, предложил пользователем на asp.net форумах. Это также вызвало ошибку внутреннего внутреннего сервера 500, так что мне кажется, что наличие двух экземпляров <sessionState> не является чем-то, что разрешено.

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

Подробнее: sessionState изменился и сайт все еще действует, как это было, то ConnectionString не должен иметь ничего общего с этой проблемой с второй базы данных потери, это заседание. Это должно быть что-то в коде позади, я не могу придумать, что еще может быть неправильно с web.config.

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

Мы также обнаружили, что переменная сеанса все еще там, он просто не будет отображать информацию пользователя, когда он подключен к задней до подключения к базе данных.


После долгих размышлений и разочарований я спросил своего начальника, как трудно просто объединить базы данных. Несмотря на то, что в базе данных резервного копирования более 2400 записей нет, другого варианта нет. Я не ожидаю, что решение придет ко мне в ближайшее время, и я уже потратил впустую месяц на это. Спасибо всем за помощь.

Если я когда-нибудь что-нибудь придумаю, я вернусь и отредактировал этот пост!

+0

Все ваши переменные сеанса исчезают? Или это просто определенные? –

+0

Почему существует несогласованность при использовании сеанса («IB») или Session.Item («IB»)? – Pankaj

+0

Несоответствие нова. Он не работал с 'Session (« IB »), поэтому я все их сменил на' Session.Item', когда я больше читал о сеансах на msdn. Я, должно быть, не получил их всех. :/И это '' Session («IB») 'исчезает. Без него он не может получить переменные «First_Name», «Last_Name» или «Name». – jlg

ответ

2

Прежде всего, удалите свой код в разделе Init на странице. Это не так.

Во-вторых, почему вы устанавливаете значения IB для сеанса True в частях вашего кода? Это перезапись номера учетной записи. Изменение обоих ..

Session("IB") = True 

в

Session("IB") = args.Value 

Или просто даже не возиться с сессией в то point..it уже должно быть установлено от IBTextBoxButton_Click Sub Routine.

+0

Это проблема с использованием других форумов перед stackoverflow ... Люди предлагают изменения, а затем stackoverflow говорит мне, что они совершенно бесполезны! hah – jlg

+1

Нельзя сказать, что каждое предложение по StackOverflow (включая мое собственное) всегда лучшее, но это всегда отличное место, чтобы начать с вопросов программирования. – N0Alias

+0

Я внес изменения, которые вы предложили, но сеанс по-прежнему не остается, когда я перехожу на другую страницу. Он по-прежнему не попадает в «Page_Load» – jlg

0

Убедитесь, что состояние сеанса включено в web.config. Если он настроен на «StateServer» или «SQLServer», замените его на «InProc» для тестирования, чтобы исключить внешние сбои.

<sessionState mode="InProc" /> 
+0

Извините, не опубликовал web.config, но это то, что я использовал. Поэтому было предложено изменить его на 'UseUri' – jlg

0

Кроме того, я видел исключения, которые были выброшены в прошлом, которые, казалось, «съедали» сеанс. Найдите любые блоки try/catch, которые могут вызвать проблемы.

Одиночный переход через код обычно показывает проблемы, но если нет, то один метод, который я использую, иногда помогает, заключается в том, чтобы помешать вашему коду сообщениями «Я здесь».

Мысль о том, что иногда это помогает вызвать прозрение, когда вы можете видеть, какая линия (или близко к ней) создает проблему.

Например, вы можете сбросить состояние переменной сеанса вместе с приблизительным номером строки и просто вывести его на несколько точек на свою веб-страницу.

Вы также должны попытаться сузить количество кода, который вы отлаживаете.

Если вы можете изолировать проблему от меньшего набора кода, часто это помогает выявлять проблемы.

** Редактировать ** Видимо, я просто просматривал. Фактически прочитав сообщение, я вижу, что вы определили строку, вызывающую проблему. Я не вижу ничего плохого в строке, но по какой-то причине я хочу попробовать использовать другое имя переменной сеанса. Я не знаю, поможет ли это, но попробовать это легко. Возможно, используйте более длинное имя переменной сеанса. Не открывая отладчика передо мной, я не знаю, что еще проверить на моей голове.

+0

. Я изменил имя' Session' на 'BAccount', и он по-прежнему переходит прямо к' Nothing', когда я нажимаю ссылку, чтобы перейти на другую страницу. Я буду продолжать исследовать, почему моя сессия не сохраняется. Было бы хорошо, если бы у меня было только 1 страница на моем сайте .... – jlg

+0

Да, это очень странно. Хотя другие переменные сеанса сохраняются? Если это так, ваш сеанс хранится в памяти или в базе данных? Если база данных, возможно, поместите трассировку в базу данных и убедитесь, что она хранит сеанс. Вы также можете создать отдельный проект с двумя страницами и провести там тестирование. Это может упростить или показать другое поведение. –

+0

'SessionState' установлен в' InProc', должен ли я попробовать другой режим? Я не уверен, как все они работают, но когда я читаю, мне кажется, что мне, возможно, придется поиграть с «режимами состояния сеанса» в ближайшее время. – jlg

Смежные вопросы