Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Error: Object reference not set to an instance of an object

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
Hello

I am getting the following server error message from my aspx page (newPassword.aspx) that allows for a user to change his password after he has forgotten his old one.

The user does that by clicking on a link sent to him via email after he has typed in his email in my forgor.aspx page. The email to the user works as does the link, but not when he presses 'Send' after typing in a new password. There are no rules such as 'you cannot have the same password twice', etc.

Object reference not set to an instance of an object.

Code:
   Stack Trace: 

   [NullReferenceException: Object reference not set to an instance of an object.]
   newPassword.resetBtn_Click(Object sender, EventArgs e) +658
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +9815206
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +204
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +12
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +15
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   +1639

Which part of my code - which I can copy and paste here - should I be looking at as the source of the problem, please?

Thank you.
 
Joined
May 20, 2005
Messages
104,556
Did you read the stack trace? It's telling exactly what method the exception was thrown in. That's what stack traces do. They tell you exactly what methods were being executed at the time and the one at the top was the last one called.
 

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
This discussion

https://stackoverflow.com/questions/131053/object-reference-not-set-to-an-instance-of-object

suggests that the error message, 'object reference not set to an instance of object', means that a variable I have used = nothing. I assume that means 'redundant', so why use it? Another contributor to the discussion states that 'when working with databases, you can get this error when you try to get a value from a field or row which doesn't exist - you get the object "reference not set to an instance of object" if tablename doesn't exists in the Dataset. The same for rows or fields in the datasets.'. I have checked my table name and the fields and rows in my own MDB (see attached screenshot, DB.jpg, please)

View attachment 158333

and they correspond to my code:

Code:
Using conn As OleDbConnection = New OleDbConnection(System.Configuration.ConfigurationManager.ConnectionStrings("students").ConnectionString)

            If Not Page.IsPostBack Then

                  cmd = New OleDbCommand("SELECT strEmail,uniqueCode FROM university" & vbTab & "WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)", conn)
                cmd.Parameters.AddWithValue("@uniqueCode", Convert.ToString(Request.QueryString("uniqueCode")))
                cmd.Parameters.AddWithValue("@strEmail", Convert.ToString(Request.QueryString("strEmail")))

            End If

            dr = cmd.ExecuteReader()

        End Using

so I don't think the error is database-related. I assume also that if the user's email address that he has typed in in the online form field (http://www.dimadayoub.net/forgot.aspx) is incorrect or one or more fields in my table are incorrect, that I would not have been redirected to the 'reset your password' field after the user has clicked on the reset link in the email he receives.

So the error must lie elsewhere. From what I can see in my code, all the variables declared are equal to something.

So I am a bit stuck!

Thanks
 

OptionBase1

New member
Joined
Nov 22, 2017
Messages
987
I hope that screenshot you just posted doesn't contain valid usernames and passwords. And, even if those are "test" accounts or something, it demonstrates that you are storing passwords in plain text.

You have fields for hash and salt, so maybe you are working your way through the process of doing this all the right way and are in the early stages of development where you just want to have the passwords plain text for testing purposes.

I'm assuming there is more code than what you've posted that gets ran when someone goes through the process of setting a new password. Without seeing more code, though, all I can do is speculate that you are missing a "New" somewhere in your code when you are trying to create an object.
 

si_the_geek

Super Moderator
Joined
Jul 29, 2002
Messages
41,398
This line:
Code:
            dr = cmd.ExecuteReader()
...should be BEFORE the End If, because the variable cmd will only be set up when the If block is entered (so it is only worth .ExecuteReader when you run the other code too).
 

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
Thanks, OptionBase1 for your reply.

The rest of the code on the aspx.vb file looks like this:

Code:
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load

      Using conn As OleDbConnection = New OleDbConnection(System.Configuration.ConfigurationManager.ConnectionStrings("students").ConnectionString)

            If Not Page.IsPostBack Then

                cmd = New OleDbCommand("SELECT strEmail,uniqueCode FROM university" & vbTab & "WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)", conn)
                cmd.Parameters.AddWithValue("@uniqueCode", Convert.ToString(Request.QueryString("uniqueCode")))
                cmd.Parameters.AddWithValue("@strEmail", Convert.ToString(Request.QueryString("strEmail")))

                dr = cmd.ExecuteReader()

            End If

        End Using

        lblExpired.Text = "Reset password link has expired"

        lblExpired.Visible = True

        Return

        dr.Close()
        dr.Dispose()

        End Sub

   Protected Sub resetBtn_Click(sender As Object, e As System.EventArgs)

        Using conn As OleDbConnection = New OleDbConnection(System.Configuration.ConfigurationManager.ConnectionStrings("students").ConnectionString)

            Dim Sql As String = "UPDATE university SET uniqueCode='',[password]=@password WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)"

            Dim cmd As New OleDbCommand(Sql, conn)

            conn.Open()

            cmd.Parameters.AddWithValue("@uniqueCode", Convert.ToString(Request.QueryString("uniqueCode")))
            cmd.Parameters.AddWithValue("@password", txtNewPwd.Text.Trim())
            cmd.Parameters.AddWithValue("@strEmail", Convert.ToString(Request.QueryString("strEmail")))

            cmd.ExecuteNonQuery()

            lblStatus.Text = "Password updated"

            lblStatus.Visible = True

            txtNewPwd.Text = String.Empty

            txtConfirmPwd.Text = String.Empty

        End Using

        End Sub

Yes, the passwords in the screenshot are fictitious. I haven't got round to working on the salt/hash yet - I need to resolve this password reset problem first, but thanks for pointing it out.

Steve
 

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
Thanks si_the_geek

I have corrected it in the code I have posted in my reply to OptionBase1.

I will upload the amended file and see if the error persists.
 

OptionBase1

New member
Joined
Nov 22, 2017
Messages
987
One thing I noticed is that in your resetBtn_Click method you are declaring your cmd variable with a Dim statement, but in Page_Load you aren't.

At the very least, for consistent code, I would use this in Page_Load:

Code:
Dim cmd As New OleDbCommand("SELECT strEmail,uniqueCode FROM university" & vbTab & "WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)", conn)
 

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
Can I ask if I have dr.Close in the wrong place because I get the following error using the code posted to OptionBase1:

ExecuteReader requires an open and available Connection. The connection's current state is closed.

In my code, isn't ExecuteReader open and available before the connection is closed?

Code:
  dr = cmd.ExecuteReader()

            End If

        End Using

        lblExpired.Text = "Reset password link has expired"

        lblExpired.Visible = True

        Return

        dr.Close()
        dr.Dispose()

Thanks again
 

OptionBase1

New member
Joined
Nov 22, 2017
Messages
987
What is dr and where/how is it defined?

Why do you have that Return statement?

Why do you have that code after the Return statement? If dr is only used inside of your If Not IsPostBack block, then the closing and disposing of dr should also be inside that If Not IsPostBack block, but I'm not entirely following what you are trying to accomplish inside of Page_Load, so I don't know what additional code you need or what code you have that you may not need.

Also, in ResetBtn_Click you have a conn.Open statement, so I'm not sure why you wouldn't have one in Page_Load as well.
 
Last edited:

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
I see what you mean. The code is more sloppy than I thought. This is what I have now:

Code:
 If Not Page.IsPostBack Then

                'Check if the email address and generated unique code is same then the panel for resetting password will be visible otherwise not

                Dim cmd As New OleDbCommand("SELECT strEmail,uniqueCode FROM university" & vbTab & "WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)", conn)

                cmd = New OleDbCommand("SELECT strEmail,uniqueCode FROM university" & vbTab & "WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)", conn)
                cmd.Parameters.AddWithValue("@uniqueCode", Convert.ToString(Request.QueryString("uniqueCode")))
                cmd.Parameters.AddWithValue("@strEmail", Convert.ToString(Request.QueryString("strEmail")))

                dr = cmd.ExecuteReader()

                dr.Close()
                dr.Dispose()

            End If

        End Using

        lblExpired.Text = "Reset password link has expired"

        lblExpired.Visible = True

        Return

        'dr.Close()
        'dr.Dispose()

Before, the dr.Close was unrelated to ExecuteReader on account of the EndIf EndUsing statements.

I will compile it and test it again.

Thanks again for your time.
 

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
I just don't understand this. Having incorporated your conn.Open(), I now get:

Parameter @uniqueCode has no default value.

What exactly is it looking for? The error seems to support the comment I quoted in my #3 that 'the error message, 'object reference not set to an instance of object', means that a variable I have used = nothing.
 

OptionBase1

New member
Joined
Nov 22, 2017
Messages
987
This is the nature of "crash at the first error" troubleshooting. Your code had (and possibly still has) multiple issues, and you need to work through them one at a time. Declaring cmd with Dim got rid of your first issue, doing a conn.Open got rid of the next one, and here you are at the third issue.

I'm unable to assist further at this time, hopefully someone else can give you some more pointers.
 
Joined
May 20, 2005
Messages
104,556
Firstly, why are you creating two commands? Secondly why are you pointlessly concatenating a Tab character into your SQL? As for the issue, have you actually debugged and determined exactly what value is being used to set that parameter? You don't just look at your code and throw your hands up because it looks right. You execute it and watch it line by line to make sure it actually does what you expect. If an error message tells you that a value is wrong then you look at that value, not just the code that uses it.
 

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
Thanks again.

This line points to the possible culprit, highlighted in VS, and the Exception Assistant appears:

Code:
dr = cmd.ExecuteReader()

System.Data.OleDb.OleDbException was unhandled by user code
  ErrorCode=-2147217904
  HResult=-2147217904
  Message=Parameter @uniqueCode has no default value.
  Source=Microsoft JET Database Engine
  StackTrace:
       at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
       at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
       at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
       at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
       at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
       at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
       at System.Data.OleDb.OleDbCommand.ExecuteReader()
       at newPassword.Page_Load(Object sender, EventArgs e) in C:\Users\Steve\Documents\Visual Studio 2013\DimaFinal\newPassword.aspx.vb:line 34
       at System.Web.UI.Control.OnLoad(EventArgs e)
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
  InnerException:

MSDN here: https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(EHOleDb);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);k(DevLang-VB)&rd=true

indicates that my database connection code is suspect. The error, that is, Parameter @uniqueCode, has no default value, and is generated when a warning or error is returned by an OLE DB data source.

So it seems to be a database problem.
 
Joined
May 20, 2005
Messages
104,556
So it seems to be a database problem.

Most unlikely. The warning returned by the OLE DB data source would be as a result of the SQL that you are sending to it being wrong. It's telling you that something is wrong with one of your parameters. It's telling you which parameter. It's telling you wants wrong with it. Why aren't you investigating that parameter, as I already suggested? I'd wager that this:
Code:
cmd.Parameters.AddWithValue("@uniqueCode", [B][U][COLOR="#FF0000"]Convert.ToString(Request.QueryString("uniqueCode"))[/COLOR][/U][/B])
is returning Nothing. That would be how a parameter has no value. ADO.NET doesn't work with Nothing. Database nulls are represented in ADO.NET by DBNull.Value.

By the way, what's the point of that Convert.ToString call? Indexing a NameValueCollection, which that QueryString property is, already returns a String reference so what does converting that String to a String do for you?
 

SteveHi

New member
Joined
Jun 4, 2014
Messages
469
I have now changed

Code:
 'cmd = New OleDbCommand("SELECT strEmail,uniqueCode FROM university" & vbTab & "WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)", conn)

to

Code:
 cmd = New OleDbCommand("SELECT strEmail,uniqueCode FROM university WHERE uniqueCode=@uniqueCode AND (strEmail=@strEmail)", conn)

and will work my way through your other points. I did take up your idea about going through the code line by line, but I never got as far as these two lines that you refer to:

Code:
 cmd.Parameters.AddWithValue("@uniqueCode", Convert.ToString(Request.QueryString("uniqueCode")))
 cmd.Parameters.AddWithValue("@strEmail", Convert.ToString(Request.QueryString("strEmail")))

Concerning those two lines, I will remove the 'Convert.ToString' as the job has already been undertaken by QueryString.

Thanks again.
 
Joined
May 20, 2005
Messages
104,556
Request.QueryString is a NameValueCollection. The Item property of a NameValueCollection, which you are invoking by indexing the property that way, will return a String containing the value for the specified key if it exists and Nothing if the key does not exist. All that is available in the documentation and takes a couple of minutes to access after clicking on the QueryString property and pressing F1. If there is no "uniqueCode" in your query string, you will get Nothing for the Value of that parameter and that will lead to an error when the database tries to process your query and, I believe, that error message.
 
Top