2011-05-31 53 views
1

我遇到了一个“奇怪”的情况与一个活的ASP.NET MVC 3应用程序。 X小时使用后生产中的错误开始。我没有能够在我的开发机器上重现错误。只有一个布尔检查if语句的NullReferenceException

这里是我的控制器操作的签名:

[HttpPost] 
public ActionResult AddBanking(int id, int? page, int bankId, 
    string q, int? searchFlag, string query, string accountNo, 
    string accountManager, bool? personnal, int? branchId, 
    int? selectedId, BankSearchModel data) 

的基本思路是,该控制器使用了对视图两种形式,一种用于搜索,其中searchFlag是一个隐藏字段和另一种形式的加入,在这里是一个基本的代码结构。很长一段时间的应用程序运行完美地后发生

try 
{ 
    if (searchFlag.HasValue) 
    { 
    var vm = svc.FetchBanks(bankId, q); 

    return View(vm); 
    } 
    else 
    { 
    bool valid = true, isIndividu = false; 

    // some code 

    if(!valid) // <- this is where the line 106 is 
    { 
    } 
    } 
} 
catch(Exception ex) 
{ 
    ex.Data.Add("context", "AddBanking - THIS IS IT"); 
    Log.Error(ex); 
    return RedirectToAction("Error", new { id = 0 }); 
} 

错误,突然,那异常被捕获,但是当用户提交的第一形式(搜索 - > searchFlag = 1),所以在我的例子它进入了第一个if语句。

这是错误和堆栈跟踪

context: AddBanking - THIS IS IT 

    Message: Object reference not set to an instance of an object. 
    Stack: 
     at XYZ.Controllers.BanksController.AddBanking(Int32 id, Nullable`1 page, Int32 
bankId, String q, Nullable`1 searchFlag, String query, String accountNo, String 
accountManager, Nullable`1 personnal, Nullable`1 branchId, Nullable`1 selectedId, 
BankSearchModel data) in E:\Projects\XYZ\ABC\123.Web\Controllers\BanksController.cs:line 
106 
  1. 它怎么可能抛出的异常在if语句与非空的布尔?
  2. 由于在我的第一个if块中有一个返回View(),并且我100%确定它已经进入那里,所以执行甚至不应该到那里的线106上的异常如何发生。
  3. 这是发生在长时间的生产时间,昨天(8至5)这个过程的工作,今天早上爆炸异常抛出,但只在生产(Windows 2008,ASP.NET MVC 3)。从我的开发机器使用相同的数据库和相同的数据发布到页面正在工作。

我的主要问题,我想如何调试这个,起初我认为栈跟踪没有返回正确的行号,所以我在操作中添加了try/catch,但它仍然返回如果(!有效)作为NRE ...

我会很感激任何想法/指导线。当然,我可以将动作中的两个过程分开,它可以解决这个问题,但我更想明白我在这个例子中做错了什么。

编辑:我完全一无所知 当我问到这个问题时,曾页没有任何代码变化和发布完全相同的数据。

编辑2 @ 2011-06-01 10:30

感谢您的建议,但我真的认为这是真正的东西更难找到。该错误今天重新出现,但应用程序在我发布此问题后1小时后才工作,直到今天@上午10点。

下面是详细什么我迄今所做试图了解发生了什么事情:

  1. 我已经重建了应用程序(不更改代码,并重新部署斌,视图)与.pdb文件。
  2. 我已经把try/catch语句的执行应该采取这里的每一个路径上是确切的情景:

查看:

@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary() 

    <fieldset> 
    @Html.Hidden("searchFlag", 1) 
    @Html.Textbox("q") 
    <input type="submit" value="Chercher" /></td> 
    </fieldset> 
} 

SVC不能为空,因为我有它设置

[Authorize] 
public class BanksController : BaseController 
{ 
    BankService svc = new BankService(); 
    ... 
} 

的FetchBanks方法

:所述控制器这样上
public BankSearchModel FetchBanks(int bankId, string query) 
{ 
    return Execute<BankSearchModel>(db => 
    { 
    try 
    { 
     // some linq stuff 
    } 
    catch(Exception ex) 
    { 
     XYZ.Log.Error(ex); // <= note1 
    }, "Error returned by Execute"); 
} 

我于是再次执行方法

protected static T Execute<T>(Func<XYZDbContext, T> query, string errorMessage, bool deferredLoading) 
{ 
    try 
    { 
    using (XYZDbContext db = new XYZ...()) 
    { 
#if DEBUG 
     db.Log = new DebuggerWriter(); 
     db.CommandTimeout = 3 * 60; 
#endif 
     if (!deferredLoading) 
     db.DeferredLoadingEnabled = false; 

     return query(db); 
    } 
    } 
    catch (Exception ex) 
    { 
#if DEBUG 
    Debug.WriteLine(ex.Message + "\r\n" + ex.StackTrace.ToString()); 
    throw; 
#else 
    ex.Data.Add("context", "Manager, executing query"); 
    XYZ.Log.Error(ex); 
    return default(T); 
#endif 
    } 
} 

,据我所知,线106并非是真正的错误在这里,但我必须在每一个方法的try /导管的执行应该去searchFlag时设置为1(从视图的第一种形式开始)。仍然唯一的Log.Error(前)我得到的是告诉我,我的控制器在106线有错误。

注1如果错误将来自FetchBanks方法它将进入catch在那个方法里面并且发送给我并且发送带有该方法的栈跟踪的电子邮件

在我的FetchBanks结束时,我返回一个BankSearchModel,它与所有List一样,以便在返回到控制器之前执行所有数据库查询。

再次,它是如何工作的相同的数据发布整天,并突然停止工作。这可能是因为我的空对象的控制器的签名会导致这种行为?

这是我在添加try/catch之后得到的唯一一封应该向我发送错误的邮件。即没有其他方法进入他们的catch(执行,FetchBanks)只有控制器行动。我真的很想了解发生了什么事。

New error occured at 6/1/2011 9:48:13 AM 

context: AddBanking - THIS IS IT 

Message: Object reference not set to an instance of an object. 
Stack: 
    at XYZ.Web.Controllers.BanksController.AddBanking(Int32 id, Nullable`1 page, Int32 

bankId,串Q,可空1 searchFlag, String query, String accountNo, String accountManager, Nullable 1周的personnal,可空1 branchId, Nullable 1 selectedId, BankSearchModel数据) E:\项目\ HiddenForObiousReason \控制器\ BanksController.cs:线106

+1

很明显,该if语句不会引发异常。您可能在源文件和二进制文件或PDB文件之间存在不匹配。重新构建应用程序(在DEBUG配置中),重新部署并希望重现。确保包含.PDB文件。 – 2011-05-31 15:57:44

+0

PDB已经在服务器上,但我正在使用发布模式进行部署。我知道这一行“可能”是抛出异常的那一行:var vm = svc.FetchBanks(bankId,q);但我有一个try/catch在该方法“FetchBanks”,应该有记录任何异常,如果这是... – 2011-05-31 16:05:01

+0

...如果'svc'为空,则不是。 – 2011-05-31 16:29:32

回答

0

将我的动作分解为两个独立动作(对于视图中的两种形式)后,我发现错误与第二种形式有关,并且与通过的模型的验证有关。

这里是我现在两个动作:

[HttpPost] 
public ActionResult AddBanking(int id, int? page, int bankId, string q) 

[HttpPost] 
public ActionResult CreateBanking(int id, int? page, int bankId, string query, string 
accountNo, string accountManager, bool? personnal, 
int? branchId, int? selectedId, BankSearchModel data) 

第一种形式张贴时抛出的错误,但是Html.ValidationSummary不写到视图的任何错误。在分离操作之后,第一个表单上不会出现错误,但仅在第二个表单上显示,现在ValidationSummary正在写入视图。这是正常的,我知道第一种形式现在不验证模型。

我还不能完全理解为什么错误每天15分钟一次(从上午8点到下午5点)提高。如果有人有解释,我将不胜感激。为什么具有完全相同数据的表单发布起作用并且后来不起作用(由于模型验证是导致错误的原因,所以这两个帖子应该失败)。

这可能是我的错误,有两个不同的功能1行动。

0

要调试这个,检查对象为null。

我不会担心第106行这么多,请检查代码中的对象为null。

例子:

if (svc == null) 
{ 
    Log.Error(new Exception("svc is null!"); 
} 

你有很多在方法调用的字符串,字符串默认为空,如果他们是未分配的,所以这可能是错误的来源。

+0

svc不能为空,它在Controller类上被实例化为受保护的变量。 (穷人的DI)。至于空字符串,在第一个if中使用的唯一字符串是“q”,我看到用户输入字符串并通过SharedView获取错误。既然在第一个返回视图if中,我会认为else块没有被评估?是的,我确定它进入了这个if语句。此代码几乎每天工作22小时。在我写这个问题的时候,我的SharedView会话之后,我重新测试了与用户完全相同的数据“q”,并且它工作了(不重建,不部署) – 2011-06-01 14:35:58

+0

如果错误是个谜,我仍然会添加额外的调试/在此方法中追踪以查看变量的内容。你可以在catch中做到这一点,以避免性能问题,并调用另一种方法来写出所有变量,并测试每个变量为null以查看哪一个正在抛出null refrence异常。那么一旦问题解决了,就取出另外登录的异常。我认为这是你解决这个谜团的最佳选择。 – 2011-06-01 15:31:16