|
-
Nov 28th, 2003, 04:50 AM
#1
Thread Starter
Lively Member
Difficult problem error -sesssion variable workaround
Hi all,
I am new to .Net and have a frustrating problem.
We have a peice of code that works, but every now and then we get the attached error. It works fine, but then after many transactions this error pops up. Once the error has popped up - we cant use the page for a while (maybe until the session times out.)
Please take alook...thanks
error:
VB Code:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 37: 'Response.Write(drData)
Line 38: 'Response.End()
Line 39: While drData.Read
Line 40: strAspxPageToCall = drData("AspxPageToCall")
Line 41: ' Response.Write(strAspxPageToCall)
Source File: \\Prxdevtest\Projects\LGWSETA\AdminTools\ToAspxDisplay.aspx.vb Line: 39
Stack Trace:
[NullReferenceException: Object reference not set to an instance of an object.]
AdminTools.ToAspxDisplay.Page_Load(Object sender, EventArgs e) in \\Prxdevtest\Projects\LGWSETA\AdminTools\ToAspxDisplay.aspx.vb:39
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +29
System.Web.UI.Page.ProcessRequestMain() +724
The code is a work around because we cant pass session variables in .net - so we write the session variables to a database and read them back.
You are living a pacifist dream, and if you dreaming it means you sleeping and you should damn well wake up!
-
Nov 28th, 2003, 04:53 AM
#2
Thread Starter
Lively Member
the code
here is the code for the page the error refers to...
VB Code:
Public Class ToAspxDisplay
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim intXaToAspxNo As Integer
Dim strSql, strAspxPageToCall As String
Dim clsPraxisDb As New AdminTools.prx.db_lib()
Dim drData As SqlClient.SqlDataReader
intXaToAspxNo = Request.QueryString("Value")
strSql = "SELECT SessionName, SessionValue, AspxPageToCall " & _
"FROM xaToAspx INNER JOIN xaToAspxSessionList ON xaToAspx.xaToAspxNo = xaToAspxSessionList.xaToAspxNo " & _
"INNER JOIN xaPageAndSession ON xaToAspx.xaPageAndSessionNo = xaPageAndSession.xaPageAndSessionNo " & _
"WHERE xaToAspx.xaToAspxNo = " & intXaToAspxNo
clsPraxisDb.DBConnectionString = Application.Contents("ConnectionString")
clsPraxisDb.makeSQLConnection()
clsPraxisDb.SQLStatement = strSql
drData = clsPraxisDb.getRecords
While drData.Read
strAspxPageToCall = drData("AspxPageToCall")
Session.Add(drData("SessionName"), drData("SessionValue"))
End While
clsPraxisDb.execNonQuery("DELETE FROM xaToAspxSessionList WHERE XaToAspxNo = " & intXaToAspxNo)
clsPraxisDb.execNonQuery("DELETE FROM xaToAspx WHERE XaToAspxNo = " & intXaToAspxNo)
Response.Redirect(strAspxPageToCall)
End Sub
End Class
You are living a pacifist dream, and if you dreaming it means you sleeping and you should damn well wake up!
-
Nov 28th, 2003, 05:00 AM
#3
Thread Starter
Lively Member
I must be honest,
I have never used .Net before. The guy that did the above code left and I have no clue how to fix.
Shoudl he have closed the datasets and things like that??
i.e. set clsPraxisdb = nothing or .close....
or something along thos lines?
I know that in ASP or VB I also set them to nothing or close them to make sure they dont hang around....
or clsPraxisDB.closeSQLConnection()
Thanks in advance everyone who helps...
You are living a pacifist dream, and if you dreaming it means you sleeping and you should damn well wake up!
-
Nov 28th, 2003, 08:41 PM
#4
Hyperactive Member
Well, I'm not sure what the insides of that class do, but you'll wanna test and see if your DataReader returned from the getRecords method is null(nothing):
VB Code:
If Not drData Is Nothing Then
While drData.Read
...
End While
End If
This is pretty horrible code, you guys should be glad the original author is no longer with you. You might wanna check this out for reference http://msdn.microsoft.com/library/de...Guidelines.asp
-
Dec 2nd, 2003, 02:37 AM
#5
Thread Starter
Lively Member
Thanks, I will try that and I agree that the code is terrible. ALso, thanks for the link - I have sent it around and will make it part of our .NET coding standards.
The thing is that its unlikely that the data is null. The error seems to occur either after a certain number of transactions OR when two people log in and use the page at the same time.
Any one ever heard of anything like that before? And dont you think it has anything to do with setting the recordsets to nothing?
You are living a pacifist dream, and if you dreaming it means you sleeping and you should damn well wake up!
-
Dec 2nd, 2003, 09:45 AM
#6
Hyperactive Member
Generally you'll want to use a Close and Dispose pattern for database stuff; and you'll wrap that code inside of Try..Catch blocks. Setting objects to nothing or null is different in .net; it's not like in vb6 and earlier where the reference count to your object is decremented by 1 by setting your object variable to nothing. It's all garbage collection these days. You'll have to check out that other guys(or girls) class that handles the database code to ensure that it ALWAYS closes an open connection and always disposes of any object that supports IDisposable(like the connection and command objects), here are some examples:
- using the close and dispose pattern:
VB Code:
Imports System
Imports System.Data
Imports System.Data.SqlClient
Public Class CloseDisposePattern : Inherits System.Web.UI.Page
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
Dim connString As String = "user id=sa;password=sa;database=scratch;server=(local);"
Dim cn As New SqlConnection(connString)
Dim cmdText As String = "Select * From..."
Dim cmd As New SqlCommand(cmdText, cn)
Dim dr As SqlDataReader
Try
cmd.Connection.Open()
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
If Not dr Is Nothing Then
While dr.Read
'do something with the datareader
End While
End If
Finally
If Not dr Is Nothing Then
dr.Close()
End If
If Not cn Is Nothing Then
cn.Close()
cn.Dispose()
End If
If Not cmd Is Nothing Then
cmd.Dispose()
End If
End Try
End Sub
End Class
This can get to be a lot of typing so it's common to write a helper class that handles the grunt work:
VB Code:
Public Class DAL : Implements IDisposable
Private _disposed As Boolean = False
Private _cn As SqlConnection
Private _connString As String
Public Function ExecuteReader(ByVal cmd As SqlCommand) As SqlDataReader
initConnection()
cmd.Connection = _cn
Return cmd.ExecuteReader(CommandBehavior.CloseConnection)
End Function
Public Sub New()
_connString = "user id=sa;password=sa;database=scratch;server=(local);"
End Sub
Private Sub initConnection()
_cn = New SqlConnection(_connString)
End Sub
Sub Dispose() Implements IDisposable.Dispose
If _disposed = False Then
cleanUp()
_disposed = True
'Make sure the Finalize method is not called
GC.SuppressFinalize(Me)
End If
End Sub
Protected Overrides Sub Finalize()
cleanUp()
End Sub
Private Sub cleanUp()
If Not _cn Is Nothing Then
_cn.Close()
_cn.Dispose()
End If
End Sub
End Class
Then all the client would do to use this would be:
VB Code:
Public Class CloseDisposePattern : Inherits System.Web.UI.Page
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
Dim cmdText As String = "Select * From..."
Dim cmd As New SqlCommand(cmdText)
Dim dr As SqlDataReader
Dim dal As New DAL
Try
dr = dal.ExecuteReader(cmd)
If Not dr Is Nothing Then
While dr.Read
'do something with the datareader
End While
End If
Finally
If Not dr Is Nothing Then
dr.Close()
End If
If Not cmd Is Nothing Then
cmd.Dispose()
End If
If Not dal Is Nothing Then
dal.Dispose()
End If
End Try
End Sub
End Class
Now that I'm looking at it, VB.NET sure seems wordy. In C# the same client code looks like this(dispose code for each item in the using statement is automatically handled):
PHP Code:
protected override void OnInit(System.EventArgs e)
{
SqlDataReader dr = null;
string cmdText = "Select * From ...";
using (DAL dal = new DAL())
using (SqlCommand cmd = new SqlCommand(cmdText))
{
try
{
dr = dal.ExecuteReader(cmd);
if (dr != null)
{
while(dr.Read())
{
//do something
}
}
}
finally
{
if (dr != null)
{
dr.Close();
}
}
}
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|