2010-08-03 47 views
1

對我來說似乎是這樣的,因爲幾乎所有向控制器發出的路由請求的下游拋出的異常都會拋入控制器或控制器的下游。控制器除了視圖之外沒有任何上游,這僅僅是控制器中發生的情況的呈現。MVC控制器層是錯誤處理的理想場所嗎?

+0

但是如果視圖中有一些錯誤呢? – 2010-08-03 11:44:38

+3

@ajay - 那麼你做錯了。你不應該在只顯示數據的東西上遇到HTTP 500。所有邏輯,數據連接,模型綁定等應該在控制器/模型中發生,而不是在視圖中。 – Tommy 2010-08-03 11:52:18

+1

@Tommy不是真的,這個視圖當然只是顯示數據,但是它可以訪問模型,通常這不僅僅是一個簡單的數據容器,因此可能會導致拋出異常。所以不要假設你的視圖不會拋出異常。 – Mendelt 2010-08-03 12:05:50

回答

2

控制器操作是大多數錯誤處理的理想場所,但不是全部。

直到控制器操作完成執行後纔會呈現視圖。因此,例如,如果將視圖傳遞給不僅僅是簡單數據容器的視圖模型,而且在呈現視圖時引發異常(並非罕見情況)。在控制器操作中你無法理解這一點。

這裏是一個工具,你可以用它來捕捉控制器 http://www.hanselman.com/blog/ELMAHErrorLoggingModulesAndHandlersForASPNETAndMVCToo.aspx

+0

已經從開始就使用Elmah :-) – ProfK 2010-08-03 13:06:45

1

它通常通過查看你需要顯示在較低的水平如出現這樣的錯誤控制器確定外例外BLL/DAL,仍然可以進行錯誤處理並且可以由控制器輔助,例如,

public ActionResult DisplayObject(int id) 
{ 
    // high level error handling 
    using (MyRepo repo = new MyRepo()) 
    { 
     var obj = repo.GetObj(id); 
     if (obj == null) 
      return View("ErrorDisplayingObject"); 
     else 
      return View("ObjectDetails"); 
    } 
} 
... 

public ActionResult SaveObject(int id, string param1, string param2) 
{ 
    // high level error handling 
    using (MyRepo repo = new MyRepo()) 
    { 
     var obj = repo.GetObj(id); 
     if (obj != null) 
     { 
      obj1.Param1 = param1; 
      obj2.Param2 = param2; 
      if (repo.Save()) 
       return View("SaveConfirmation"); 
     }   
    } 
    return View("ErrorSavingObject"); 
} 

... 
public class MyRepo 
{ 
    public MyObject GetObj(int id) 
    { 
     // low level error handling 
     try 
     { 
      // retrieve object 

     } 
     catch (Exception) 
     { 
      return null; 
     } 
    } 

    public bool Save() 
    { 
     // low level error handling 
     try 
     { 
      // save data 
      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 
} 
+0

我完全同意這種較低級別的錯誤處理,只是不像你這樣做。如果某些東西不能保存,爲什麼返回false?爲什麼不讓這個例外冒出來呢? – ProfK 2010-08-03 12:28:49

+0

@ProfK:你的確可以讓它起泡,上面只是你可以做到的很多方法的一個例子:)個人...我會一直讓異常冒出來,因爲你想知道*完全*爲什麼它從來沒有保存,甚至在視圖本身輸出。 – James 2010-08-03 13:04:22

1

模型必須是您可以進行驗證的最合適的地方。理想情況下,模型必須是域模型應該放置的地方。因此,這使得它成爲錯誤驗證的理想場所。

+0

爲模型歡呼。控制者應該是精益和平均的。模型應該很胖。實際上,我將驗證和數據訪問分解爲服務和存儲庫層。但是 - 這是模型驗證的良好開端,http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx – gnome 2010-08-03 14:04:14

1

它取決於異常和您的操作。例如,如果您保存的實體可能會破壞某些業務規則,那麼預計您的BLL會拋出一個異常(例如BusinessRuleXXException)來表示這種不合規情況。在這種情況下,您必須處理該異常(控制器是做這件事的好地方),並向用戶顯示一條適當的消息,指出 出了什麼問題(由於bla bla ...,您不能保存這個消息)。

在另一方面,你可能在至極 you're執行某些動作的越野車應用程序,你挑起的錯誤,例如像被違反了PK約束或許外部 服務不可用或任何其他情形那些預計不會在您的應用程序中代表真正的例外。對於這種類型的錯誤,我的建議是通過使用HandleError過濾器或自定義過濾器來處理全局錯誤,並處理錯誤 並記錄它們,並將用戶重定向到錯誤頁面,其中有一個友好的「對不起,出錯了。已經派出一支訓練有素的猴子來處理這種情況,「信息顯示。

問候。