仅带有布尔检查的 if 语句出现 NullReferenceException

发布于 2024-11-11 18:09:34 字数 4677 浏览 0 评论 0原文

我在使用实时 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)

基本思想是控制器用于视图上的两种形式,一种用于搜索,其中 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. 如何在具有不可空 bool 的 if 语句上抛出异常?
  2. 由于我的第一个 if 块中有一个 return View() ,并且我 100% 确定它进入了那里,为什么异常出现在第 106 行,执行甚至不应该到那里。
  3. 这是只有在长时间生产之后才会发生的事情,昨天(8 点到 5 点)这个过程有效,今天早上抛出了异常,但仅在生产中(Windows 2008,ASP.NET MVC 3)。从我的开发机器上,具有相同数据库和相同数据的页面发布工作正常。

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

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

编辑:我完全一无所知 当我问这个问题时,该页面可以在代码没有任何更改的情况下运行,并且发布的数据完全相同。

Edit 2 @ 10:30 2011/06/01

感谢您的建议,但我真的认为这确实很难找到。该错误今天确实再次出现,但从我昨天发布此问题后 1 小时到今天上午 10 点,该应用程序一直在运行。

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

  1. 我已经使用 .pdb 文件重建了应用程序(没有代码更改,并重新部署 bin、视图)。
  2. 我已将 try/catch 放在执行应采取的每个路径上,这里是确切的场景:

View:

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

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

svc can not be null 因为我在控制器上设置了它,如下所示:

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

The FetchBanks method

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");
}

My 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/cath ,当 searchFlag 设置为 1 时(从视图的第一种形式开始),执行应该继续。我得到的唯一的 Log.Error(ex) 是告诉我控制器在第 106 行出现错误的。

Note1 如果错误来自 FetchBanks 方法,它会进入内部的 catch该方法并向我发送带有该方法的堆栈跟踪的电子邮件。

在我的 FetchBanks 末尾,我返回一个 BankSearchModel,它作为所有列表,以便在返回控制器之前执行所有数据库查询

。对于整天发布的相同数据并突然停止工作,控制器与我的所有空对象的签名是否可能会导致这种行为?

这是我在所有应该向我发送错误的地方添加 try/catch 后收到的唯一一封电子邮件。即没有其他方法进入它们的catch(执行、FetchBank),只有控制器操作。我真的很想了解发生了什么事。

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、Nullable1 searchFlag、字符串查询、字符串 accountNo、字符串 accountManager、Nullable1 个个人、Nullable1 个branchId、Nullable1 个 selectedId、 BankSearchModel 数据)中 E:\Projects\HiddenForObiousReason\Controllers\BanksController.cs:第 106 行

I'm experiencing a "strange" situation with a live ASP.NET MVC 3 app. The error start on production after X hours of use. I did not have been able to reproduce the error on my development machine.

Here is my controller action signature:

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

The basic idea is that the controller is use for two forms on the View, one for searching where searchFlag is a Hidden field and another form for adding, here is a basic code structure.

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 });
}

The error occurs after long periods of time the app run flawlessly, all of a sudden, that exception is caught, but when the users submit the first form (for searching -> searchFlag = 1), so in my example it entered the first if statement.

This is the error and stack trace

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. How can it be possible to throw exception on a if statement with a non-nullable bool ?
  2. Since there is a return View() in my first if block, and I'm 100 % certain it entered there how come the exception is on the line 106 where the execution should not even go there.
  3. This is something that happen only after long period of production time, yesterday (8 to 5) this process worked, and this morning bang the exception is throwing, but only in production (Windows 2008, ASP.NET MVC 3). From my developement machine with the same database and same data posting to the page is working.

My main question, how am I suppose to debug this, at first I thought that the stack trace does not returned the right line number, so I added a try/catch inside the action, yet it still return the if(!valid) as NRE...

I would appreciate any idea / guide line. Of course I could separate the two process inside the action and it might fix the problem, but I would rather like to understand what I'm doing wrong in the example.

Edit: I'm completely clueless
By the time I asked this question, the page worked without any change in code and for the exact same data posted.

Edit 2 @ 10:30 2011/06/01

Thanks for your suggestions, but I'm really thinking this is really something harder to find. The bug did re-appear today but the app was working from 1 hour after I post this question yesturday until today @ 10 am.

Here is more detail on what I've done so far to try to understand what's going on:

  1. I've rebuilt the app (no code changes, and re-deploy bin, views) with .pdb files.
  2. I've put try/catch on every path that the execution should take here is the exact scenario:

View:

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

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

svc cannot be null because I have it set on the controller like this:

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

The FetchBanks method

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");
}

My Execute method

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
  }
}

So again, I understand that the line 106 is not the real error here, but I have try/cath in every single method that the execution should go when the searchFlag is set to 1 (from the first form of the view. Still the only Log.Error(ex) I got was the one telling me there is an error on my contorller at line 106.

Note1 If the error would have come from the FetchBanks method it would have entered the catch inside that method and send me and email with stack trace of that method.

At the end of my FetchBanks I return a BankSearchModel which as all List so all databases query are executed before returning to the controller.

And again, how can it work for the same data posted all day long and suddently stop working. Would that be possible that the signature of the controller with all my null object would cause that behaviour?

This is the only email I got after adding try/catch everywhere that should have send me an error. i.e no other method are entering their catch (The execute, the FetchBanks) only the controller action. I would really like to understand what's going on.

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, Nullable1 searchFlag, String query, String accountNo, String
accountManager, Nullable
1 personnal, Nullable1 branchId, Nullable1 selectedId,
BankSearchModel data) in
E:\Projects\HiddenForObiousReason\Controllers\BanksController.cs:line 106

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枕梦 2024-11-18 18:09:34

将我的操作分成两个不同的操作(对于视图中的两个表单)后,我发现错误与第二个表单有关,并且与通过的模型的验证有关。

现在这是我的两个操作:

[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 正在写入视图。这是正常的,我知道第一个表单现在不验证模型。

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

对于两个不同的功能使用 1 个操作可能是我的错误。

After separating my action into two disctinct action (for the two forms in the view) I discover that the errors was relating to the second form and related to the validation of the Model passed.

Here are my two actions now:

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

The error was thrown when the first form was posted, but the Html.ValidationSummary was not writing any errors to the view. After separating the action no error were thrown on the first form, but only on the second and now the ValidationSummary is writing to the View. That is normal and I understand that the first form now do not validate the Model.

What I still cannot fully understand exactly why the error was raising on batch of 15 minutes once a day (from 8am to 5pm). If someone has explanation I would appreciate it. Why a form post with the exact same data works and later do not work (the two posts were supposed to fail since the Model Validation was the cause of the error).

That was probably my mistake to have 1 action for two distinct functionality.

风情万种。 2024-11-18 18:09:34

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

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

示例:

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

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

To debug this, check the objects for null.

I wouldn't worry about line 106 so much, check the object(s) in the code for null.

Example:

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

You have lots of strings in that method call, strings default to null if they are unassigned, so that could be a source of the error as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文