2009-07-02 107 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方法中访问它。