仅对bool检查的if语句的NullReferenceException

时间:2011-05-31 14:02:06

标签: c# asp.net-mvc-3 nullreferenceexception

我正在使用实时ASP.NET MVC 3应用程序遇到“奇怪”的情况。 X小时使用后,错误开始生产。我无法在我的开发机器上重现错误。

这是我的控制器动作签名:

[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)

基本思想是控制器用于View上的两个表单,一个用于搜索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 });
}

错误发生在应用程序长时间运行完美之后,突然之间,异常被捕获,但是当用户提交第一个表单(用于搜索 - &gt; 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. 怎样才能在带有非可空bool的if语句上抛出异常?
  2. 由于在我的第一个if块中有一个返回View(),并且我100%确定它已经进入那里,因此异常是在第106行执行甚至不应该去那里。
  3. 这种情况只发生在经过长时间的生产时间之后,昨天(8到5)这个过程才起作用,今天早上爆炸异常就是投掷,但仅限于生产(Windows 2008,ASP.NET MVC 3)。从我的开发机器开始,具有相同的数据库并且相同的数据发布到页面上。
  4. 我的主要问题是,我想如何调试它,起初我认为堆栈跟踪没有返回正确的行号,所以我在操作中添加了一个try / catch,但它仍然返回if(!)有效)作为NRE ......

    我很感激任何想法/指导方针。当然,我可以将动作中的两个进程分开,它可能会解决问题,但我更愿意理解我在示例中做错了什么。

    编辑:我完全无能 当我提出这个问题时,页面的工作没有任何代码更改和发布的完全相同的数据。

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

    感谢您的建议,但我真的认为这真的很难找到。这个错误今天重新出现,但应用程序在我发布这个问题的一个小时后工作,直到今天上午10点。

    以下是我到目前为止所做的更多细节,试图了解正在发生的事情:

    1. 我用.pdb文件重建了应用程序(没有代码更改,并重新部署bin,视图)。
    2. 我把try / catch放在执行应该采取的每个路径上的确切场景:
    3. 查看:

      @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行不是真正的错误,但我在searchFlag设置为1(从视图的第一种形式)执行时应该执行的每一种方法都尝试使用/ cath。我得到的唯一的Log.Error(ex)是告诉我在第106行我的控制器上有错误。

      Note1 如果错误来自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,String q,Nullable 1 searchFlag, String query, String accountNo, String accountManager, Nullable 1 personnal,Nullable 1 branchId, Nullable 1 selectedId, BankSearchModel数据) E:\ Projects \ HiddenForObiousReason \ Controllers \ BanksController.cs:第106行

2 个答案:

答案 0 :(得分:0)

要调试此项,请检查对象是否为空。

我不会太担心第106行,请检查代码中的对象是否为null。

示例:

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

在该方法调用中有很多字符串,如果未分配字符串,则默认为null,因此也可能是错误的来源。

答案 1 :(得分: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正在写入View。这是正常的,我理解第一种形式现在不验证模型。

我仍然无法完全理解为什么错误是每天一次(从早上8点到下午5点)每批15分钟。如果有人有解释我会很感激。为什么具有完全相同数据的表单帖子有效并且以后不起作用(因为模型验证是导致错误的原因,这两个帖子应该失败)。

对于两个不同的功能而言,这可能是我的错误。