2009-07-02 109 views
9

在控制器中,try ... catch可以捕獲異常。如何捕捉異常?例如,一個視圖可能有這樣的代碼:如何捕捉MVC視圖的異常?

<%= Html.Encode(Model.MyID)%> 

如果型號爲空,你會得到異常,當訪問視圖。在哪裏捕捉異常並將用戶重定向到錯誤頁面,並提供用戶友好的錯誤消息?

+0

您正在使用哪種技術? – 2009-07-02 14:03:25

+0

微軟ASP.NET MVC框架 – KentZhou 2009-07-02 15:33:24

+1

我不會使用異常的非例外行爲,絕對不在視圖中。 – Paco 2009-07-02 19:23:07

回答

1

這個邏輯應該將控制器內部進行處理,而不是視圖。例如,如果您嘗試查看不存在MyID的產品,則會重定向到錯誤頁面。

如果發生錯誤,你也可以重定向到一個InvalidProduct認爲,將提供更詳細的錯誤描述/指令。

編輯:除了人民的意見如下趕上未處理的異常添加[的HandleError]屬性無論是在你的ActionResult的方法聲明或控制器上的(所有ActionResults)。

[HandleError] 
public ProductsController 
{ 
    public ActionResult Show(int id) 
    { 
     Product p = //e.g. get product from db 

     if (p == null) 
     { 
      return RedirectToAction("Error"); 
      //return RedirectToAction("InvalidProduct"); 
     } 

     return View(p); 
    } 
1

好了,你不能總是趕在控制器中的每個錯誤,但我希望你的意見應該是輕量級足夠的地方是非常不可能發生的。

但是,如果一個例外情況在視圖中拋出,你應該已經建立了將用戶重定向到剛剛在的情況下自定義500錯誤頁面。我相信你可以在Global.asax中設置這樣的重定向,或者它也可以是IIS設置。

4

只要下,[HandleError]屬性添加到您的控制器類的頂部。這樣,您的Controller生成的任何異常都將得到處理,用戶將會看到/Views/Shared/Error.aspx。傳遞給該視圖的模型是一個System.Web.Mvc.HandleErrorInfo對象。

控制器:

[HandleError] 
public class MyController : Controller 
{ 
    public ActionResult Default() 
    { 
    MyClass thing = MyClassFactory.Create(); 
    return View(thing); 
    } 
} 

這是一個爲 「不得已而爲之」 的異常處理。大衛的回答最適合那些你可以提前想到的案例。

2

雖然我支持大衛·利德爾的答案(「這種邏輯應該是你的控制器內被處理,而不是視圖」)我還可以告訴你,你應該在一般防守編碼。

例如,而不是

try 
{ 
    Html.Encode(Model.MyID) 
} 
catch 
{ 
    Response.Redirect("~/Error/500"); 
} 

你應該

if (Model == null) 
{ 
    // ... 
} 
else 
{ 
    //..... 
} 

(ofcourse,再次,不要把視圖選擇邏輯視圖)

0

你可以使用try/catch語句在視圖中的腳本塊:

@try 
{  
    <div>typical Razor view stuff here...</div> 
} 
catch (Exception ex) 
{ 
    @<script type="text/javascript"> 
    alert('@ex.Message.Replace("'","\\'").Replace("\r\n","<br/>")'); 
    </script> 
} 
0

我同意馬修格羅夫斯的觀點,你不可能總是抓住每一個錯誤。不幸的是,在我的情況下,我有一個觀點,有100個變量。很難說清所有這些。

有多種方式在這裏發現錯誤:http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine

在我的情況,我想記錄發生在與在控制器使用的數據視圖的錯誤。所以我選擇在我的控制器中重寫OnException。這樣,在操作過程中,我可以將數據存儲在控制器實例中,然後在OnException方法中訪問它。