C# IIS/ASP.net上的NullReferenceException-不知从何而来?

C# IIS/ASP.net上的NullReferenceException-不知从何而来?,c#,asp.net,iis,web-applications,webserver,C#,Asp.net,Iis,Web Applications,Webserver,我目前在一家软件公司的网站上工作。我有一个机制,在页面加载(在page_OnLoad中,母版页代码文件)时立即运行,创建自己类的新实例并从那里运行函数。 几周来一切都很顺利,我在完全不同的页面/区域工作,这些页面/区域对我目前的事业没有任何影响 因此,发生了以下情况: 我在asp.net开发服务器上尝试了这个网站:一切都很好,工作正常。所以我把它上传到我的IIS服务器上。访问该网站:一切仍在运行,没有错误。 大约20分钟后,我刷新了页面:NullReferenceException,不知从何而来

我目前在一家软件公司的网站上工作。我有一个机制,在页面加载(在page_OnLoad中,母版页代码文件)时立即运行,创建自己类的新实例并从那里运行函数。 几周来一切都很顺利,我在完全不同的页面/区域工作,这些页面/区域对我目前的事业没有任何影响

因此,发生了以下情况: 我在asp.net开发服务器上尝试了这个网站:一切都很好,工作正常。所以我把它上传到我的IIS服务器上。访问该网站:一切仍在运行,没有错误。 大约20分钟后,我刷新了页面:NullReferenceException,不知从何而来。现在不管我做什么,我都摆脱不了它

这是来自堆栈的消息:

   [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
母版页代码文件:

http://codetidy.com/3244/
调用的类:

http://codetidy.com/3245/

下面是引发异常的代码部分:

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
    }
}
问题在于第二个查询,您没有检查dtCurrent.Rows[0]是否存在

在第一个查询中,您做的是正确的—在执行任何操作之前检查dtCurrent.Rows.Count>0。您似乎只是假设,因为第一个查询返回了一个结果,所以第二个查询也会返回结果,但由于这是引发异常的地方,您可能需要重新考虑该假设

您的评论说,第二个查询的目的是“检查IP是否已注册”,但实际上您并没有检查记录是否存在——您只是假设记录存在并使用它,这使得代码在没有此类记录时失败

如果今天没有注册IP,还有记录吗?如果不是,那就是你的问题所在

对于这样的问题,我的第一反应是添加一个检查,以确保我的假设完全正确:

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
}

您是否尝试过在cUserLog.cs的第72行附近添加粒度日志记录?理想情况下,将每个组合操作分解为多个步骤,以便您可以看到它何时失败,等等?(注意:不要相信行号是准确的-它们可能有点不同,但应该很接近)问题是,当我使用中断/逐步移动代码调试代码时,一切都正常运行。@user1450661的可能重复:“当我使用中断/逐步遍历代码来调试代码时,一切都正常运行“。我假设您正在开发计算机上执行此操作,因为我怀疑您是否在生产Web服务器上运行Visual Studio。但问题不在实时服务器上吗?大概代码是一样的,但数据是一样的吗?如果您有一个不同的数据库用于调试,您不能假设正在执行相同的代码分支。谢谢您的链接。非常有用的信息!但我确实知道NullReferenceException是什么,也知道它为什么会产生。但是我不明白为什么我的实例在这种情况下是空的,在这种情况下会发生错误,而且主要是:为什么它完全是凭空发生的?不,这不可能是问题,因为总是有一条记录,所以第二个查询总是返回一行。当我使用换行符遍历代码时,我得到了一个结果行,返回了我所期望的信息。如果确实是这样的话(在我看来它仍然像是有风险的代码),那么在继续之前,您需要确定哪个对象实际为空。对于以“if(SqlCon.DateFromString(…”)开头的行,您将获得一个NullReferenceException,但该行上有多个对象,您需要在修复该问题之前确定实际为null的对象。是SqlCon?dtCurrent?dtCurrent.Rows[0]?dtCurrent.Rows[0][“date”]?尝试将步骤分开,找出哪个项为空,然后您可以找出它为空的原因。这是处理空异常的一种很好的通用方法。请注意,“总是有记录”是很容易导致您遗漏某些内容的假设之一。您的代码的假设之一必须不正确,否则不会出现此异常。您真的确定此特定假设不是问题的根源吗?可能值得再次检查记录是否确实存在。我理解您的想法nking,但我所能做的就是尝试证明我的假设(即使它是“危险的”),即在这种情况下,始终存在一条记录。如果我遍历代码并到达那一行:瞧,我得到了(正如我预期的)一行。SQLCon在这里,dtCurrent中有项,dtCurrent.Rows[0]datefield也返回了一个有效的日期,并且它被正确地解析为字符串。考虑到您的建议,并仔细检查所有内容,结果仍然是一个异常,让我们假设错误在别处,ASP.net只是给出了“易于理解的错误消息”(讽刺)因此,您的开发版本正在查找一条记录,并且正常工作,然后您假设当live版本查找一条完全不同的记录时,它一定还在查找。再次,我强烈建议您停止使用调试器单步检查开发版本,而是插入一些语句,以确保live版本确实是在寻找记录。