2011-05-31 137 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