0

I'm currently working on a website for a software company. I have a mechanism that runs as soon as the page loads (in Page_OnLoad, Masterpage code file), creates a new instance of an own class and runs a function from there. Everything was running fine for weeks, and I worked on the website at completely different pages/areas that do not affect my current cause in any way.

So the following happend: I tried the website on the asp.net dev server: Everything was fine and working correctly. So I uploaded it to my IIS server. Accessed the website: Everything still running without errors. 20 minutes or so later, I refreshed the page: NullReferenceException, out of nowhere. And now I can't get rid of it, whatever I do.

This is the message from the stack:

   [NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.]
   EITS.WWW.Helper.cUserLog.TrackUserLog(HttpRequest request) in     C:\EIT\Projekte\eits.ch\www.eits.ch\EITSWeb\www.eits.ch\Includes\cUserLog.cs:72
   EITS.WWW.IndexMaster.Page_Load(Object sender, EventArgs e) in C:\EIT\Projekte\eits.ch\www.eits.ch\EITSWeb\www.eits.ch\Index.Master.cs:22
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +24
   System.Web.UI.Control.LoadRecursive() +70
   System.Web.UI.Control.LoadRecursive() +189
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3063

The Masterpage code file:

http://codetidy.com/3244/

The class that is invoked:

http://codetidy.com/3245/
user1450661
  • 301
  • 6
  • 13
  • 2
    Have you tried adding granular logging near line 72 of cUserLog.cs ? Ideally, breaking each composite operation into steps, so you can see when it fails, etc? (note: don't trust the line numbers to be *exact* - they can be a tiny bit different, but should be *close*) – Marc Gravell Aug 06 '12 at 13:30
  • The problem is, when I debug the code using breaks / moving through the code step by step, everything is running fine. – user1450661 Aug 06 '12 at 13:39
  • possible duplicate of [What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net) – John Saunders Aug 06 '12 at 13:59
  • @user1450661: "when I debug the code using breaks / moving through the code step by step, everything is running fine". I assume you're doing that on your dev machine, since I doubt you're running Visual Studio on your production webserver. But isn't the problem on the live server? Presumably the code is the same, but is the data? If you've got a different database for your debugging, you can't assume that the same branches of code are being executed. – Chris Aug 06 '12 at 14:08
  • Thank you for that link. Very useful information there! But I know for sure what a NullReferenceException is, also why it is been caused. But I don't see why my instance is null in that case, where the error occurs and mostly: Why did it happen completely out of nowhere? – user1450661 Aug 06 '12 at 14:11
  • VS is running on my local machine, but access the same DB as the webserver, where other querys (that sometimes do exactly the same) are working like a charm! – user1450661 Aug 06 '12 at 14:19

1 Answers1

1

Here's the section of code that's throwing the exception:

String vSQL = "SELECT * FROM eits_visitor WHERE ip = '" + oUser.usrIP + "'";
DataTable dtCurrent = SQLCon.GetDataTableFromSQL(vSQL, oHelper.cfgConnection);

if (dtCurrent != null && dtCurrent.Rows.Count > 0) {
    // Check if IP is registered today
    vSQL = "SELECT TOP(1)* FROM eits_log WHERE visitor_ip = '" + oUser.usrIP + "' ORDER BY date DESC;";
    dtCurrent = SQLCon.GetDataTableFromSQL(vSQL, oHelper.cfgConnection);

    // Next line is where the exception is thrown:
    if (SQLCon.DateFromString(dtCurrent.Rows[0]["date"].ToString()).DayOfYear != DateTime.Now.DayOfYear) {
        // do stuff
    }
}

The problem is with this second query, where you're not checking that dtCurrent.Rows[0] even exists.

In the first query, you're doing the right thing - checking that dtCurrent.Rows.Count > 0 before doing anything. You seem to then just assume that because the first query returned a result, the second query will too, but since this is where the exception is being thrown you may need to rethink that assumption.

Your comment says the second query is aimed at "check[ing] if IP is registered today", but you're not actually checking whether a record exists - you're just assuming the record is there and using it, which makes the code fail when there is no such record.

If the IP wasn't registered today, is there still a record? If not, that's where your problem lies.

My first response to a problem such as this would be to add a check to make absolutely sure my assumption is correct:

if (dtCurrent.Rows.Count == 0)
    throw new Exception("The unthinkable happened - our assumption was wrong!");

// Next line is where the exception was being thrown before.
// Do we still get this far now?
if (SQLCon.DateFromString(dtCurrent.Rows[0]["date"].ToString()).DayOfYear != DateTime.Now.DayOfYear) {
    // do stuff
}
Chris
  • 4,511
  • 21
  • 25
  • Nah, that can't be the problem, as there is ALWAYS a record, so the second query ALWAYS returns a row. When I move through my code using breaks, I got a result row back with the information I was expecting. – user1450661 Aug 06 '12 at 13:45
  • If that really is the case (and it does still look like risky code to me), you need to pinpoint which object is actually null before you can proceed. You're getting a NullReferenceException for the line that begins "if (SqlCon.DateFromString(...", but there's several objects on that line and you need to pinpoint the one that's actually null before you can fix the problem. Is it SQLCon? dtCurrent? dtCurrent.Rows[0]? dtCurrent.Rows[0]["date"]? Try separating the steps to find out which item is null, then you can figure out *why* it's null. This is a good general-case approach to null exceptions. – Chris Aug 06 '12 at 14:04
  • p.s. "there is ALWAYS a record" is one of those assumptions that can easily lead to you missing something. *One* of your code's assumptions must be incorrect, otherwise you wouldn't be getting this exception. Are you *truly* certain that this particular assumption isn't the source of the problem? Might be worth double-checking that the record really does exist. – Chris Aug 06 '12 at 14:10
  • I understand your thinking, but all I can do is try to proof my assumption (even if its 'dangerous'), that in this case always a record exists. If I move through my code and come to that line: Voilà, I got (as I expected) a row back. SQLCon is here, dtCurrent has items in it, dtCurrent.Rows[0] too and the datefield returns a valid date, also it is parsed to a string correctly. Considering your suggestions and double-checking everything resulting still in a NRException let's me assume that the error is elsewhere and ASP.net is just giving his "well understandable, easy error messages" (irony) – user1450661 Aug 06 '12 at 14:15
  • Proving your assumption is exactly what you should do, yes. That isn't necessarily done just by stepping through the code on your development machine and looking at the variables there. What if the variables are different on the live server? Have your proved your assumption there? I've edited my original answer to make a suggestion about how to make absolutely sure. – Chris Aug 06 '12 at 14:24
  • @user1450661 the first query uses the column `ip`, while the second query uses the column `visitor_ip`. Are you sure that doens't cause zero results to be returned? – CodeCaster Aug 06 '12 at 14:28
  • Okay, something else for you to think about. When you run the code on your local machine, it works, correct? Well, the code in question shouldn't be running at all, since this whole section doesn't run when your IP address is localhost/127.0.0.1/::1. So I assume you're commenting out that if-statement, correct? You then go ahead and step through the code, and it looks up the records for 127.0.0.1, and everything works. Then you run it on the live server and it doesn't work - but, is you IP address still 127.0.0.1? Not if you're accessing the live version from your own machine. [cont.] – Chris Aug 06 '12 at 14:42
  • 1
    So your dev version is looking up one record, and working, and then you assume that when the live version looks up an entirely different record it must still be finding it. Again, I strongly recommend you stop just stepping through the dev version with a debugger, and instead insert some statements to make absolutely certain that the live version is indeed finding a record. – Chris Aug 06 '12 at 14:44
  • Hi there. I tried out all your suggestions, but it is still not working. @Chris: I know, but for testing purposes, I commented the if-statement for localhost-checking out, so that even localhostip is going to be processed. – user1450661 Aug 09 '12 at 19:17
  • @CodeCaster: Oh, it didn't saw that. But fixing this led to nothing new, so I assume the error occurs before that line..? – user1450661 Aug 09 '12 at 19:19