如何捕获MVC视图的异常?

时间:2009-07-02 14:02:20

标签: .net asp.net-mvc exception-handling

在控制器中,尝试... catch可以捕获异常。如何捕获异常?例如,视图可能包含以下代码:

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

如果Model为null,则在访问视图时会出现异常。在哪里捕获异常并将用户重定向到错误页面,并提供用户友好的错误消息?

8 个答案:

答案 0 :(得分:4)

只需将[HandleError]属性添加到Controller类的顶部即可。这样,您的Controller生成的任何异常都将被处理,并且将向用户显示/Views/Shared/Error.aspx。传递给该视图的模型是System.Web.Mvc.HandleErrorInfo对象。

控制器:

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

这是“最后的手段”异常处理。大卫的答案最适合你提前想到的那些案例。

答案 1 :(得分:2)

此逻辑应在Controller内处理,而不是View。例如,如果您尝试查看不存在MyID的产品,则会重定向到错误页面。

如果发生错误,您还可以重定向到InvalidProduct视图,该视图将提供更详细的错误说明/说明。

编辑:除了下面的人们注释以捕获未处理的异常之外,还要在ActionResult方法声明或Controller上添加[HandleError]属性(对于所有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);
    }

答案 2 :(得分:2)

考虑使用Elmah:http://code.google.com/p/elmah/

答案 3 :(得分:2)

虽然我支持David Liddle的回答(“这个逻辑应该在你的控制器内而不是视图中处理”)我也可以告诉你,你应该在防守方面进行编码。

例如,而不是

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

你应该

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

(当然,再次,不要在视图中放置视图选择逻辑)

答案 4 :(得分:2)

您可以在视图中的脚本块中使用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>
}

答案 5 :(得分:1)

好吧,你不能总是捕捉到控制器中的每一个错误,但希望你的观点应该是轻量级的,不太可能发生。

但是,如果视图中出现异常,则应设置自定义500错误页面以将用户重定向到以防万一。我相信您可以在Global.asax中设置这样的重定向,也可以是IIS设置。

答案 6 :(得分:1)

我同意Matthew Groves的说法,你不能总是抓住每一个错误。不幸的是,在我的情况下,我有一个视图,有100个变量。很难解释所有这些问题。

有多种方法可以在此处发现错误:http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine

就我而言,我想用控制器中使用的数据记录视图中出现的错误。所以我选择在我的控制器中覆盖OnException。这样,在操作期间,我可以将我的数据存储在控制器实例上,然后在OnException方法中访问它。

答案 7 :(得分:0)

如果要重定向到cshtml中的错误操作,请尝试以下代码:

return pkg_authorization.f_is_customer_01(:APP_USER) = 1;