【问题标题】:Exception handling in Controller in ASP.Net MVC 4 with ELMAH and ajax带有 ELMAH 和 ajax 的 ASP.Net MVC 4 中控制器中的异常处理
【发布时间】:2013-08-13 21:15:48
【问题描述】:

我看过很多帖子和文章,但无法清晰地看到解决方案。

我已经通过 NuGet 安装了 Elmah.MVC,并在 FilterConfig.cs 中注释掉了这一行:

//filters.Add(new HandleErrorAttribute());

这样 Elmah 会发现错误。

当我提供无效的操作名称并且收到黄页和电子邮件时,它会起作用。

我想知道我的代码可能产生的另外两种类型的错误......我们应该如何处理它们:

1.例如如果我的存储库或管理器(业务逻辑)层在尝试访问数据库或发送电子邮件等时抛出异常。

一个。在控制器(或其他任何地方)中不实现任何类型的 try catch 并让 Elmah 处理异常的正确方法是什么?

b.如果是这样,并且如果它显示一个黄色的错误页面,我们如何显示我们自己喜欢的视图?

2.如果我的视图包含 ajax 调用,例如通过jqgrid,在幕后有错误,我注意到它们也被Elmah正确拾取。但是我如何也向用户显示某种错误消息呢?

谢谢

【问题讨论】:

  • 我在这里找到了部分答案:stackoverflow.com/questions/16479396/…
  • 越来越近:我在控制器中放置了一个 try catch 块。在 catch 中,我写了 2 行: 1. Elmah.ErrorSignal.FromCurrentContext().Raise(ex) 2. return View("../Error/ShowException", ex)...... 现在我需要解决点 #2 并找到如何自定义 404 错误页面

标签: asp.net-mvc-4 elmah


【解决方案1】:

这是我所做的:

在控制器中,我放置了try catch:

        try
        {
            //model = getmodelfromdb();

            return View("MyView", model);
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
            return View("../Error/ShowException", ex);
        }

对于 404 的自定义视图,我在 global.asax 中执行了此操作:

    protected void Application_OnError( )
    {
        var exception = Server.GetLastError( );

        Elmah.ErrorSignal.FromCurrentContext().Raise(exception);

        Helper.SetSessionValue(SessionKeys.EXCEPTION, exception);

        Response.Redirect( "~/Error/ShowException");
    }

对于 jqgrid,我在我的控制器中这样做了:

    [HttpPost]
    public ActionResult ListRecords( int page , DateTime? fromdate , DateTime? todate)
    {

               try
               {
                 var list = FetchListFromDB();

            var result = new
                {
                    total = Math.Ceiling(list.Count / (decimal)Helper.PAGE_SIZE),
                    page = page, //--- current page
                    records = list.Count, //--- total items
                    rows = list.List.Select(x => new
                    {
                        id = x.EntityID,
                        cell = new string[] 
                {
        x.Property1,
                    x.Property2
                }
                    }).ToArray()
                };


            return Json(result, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {

            var result = new
            {
                errorMessage = "An unexpected error occurred while fetching data. An automatic email has been generated for the support team who will address this issue shortly. Details: " + ex.Message,
                records = 0
            };

            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

            return Json(result, JsonRequestBehavior.AllowGet);
        }

这在视图中(在 jqgrid 定义中):

        loadComplete:function(data)
        {
            if (data.errorMessage)
            {
                alert(data.errorMessage);
            }
        },

在一般的 ajax 场景中:

        success: function(data)
        {
            if (data.errorMessage)
            {
                alert(data.errorMessage);
            }
            else
            {
                           //...
            }
        },

【讨论】:

  • 这行得通,但我会强烈建议不要使用catch (Exception ex),除非你非常小心。捕获您期望的特定异常类型;你永远不知道什么时候这可能会捕获一些其他异常并阻止它到达正确的处理程序,或者到达调试时对你有意义的地方。我还建议不要向用户显示您的异常消息;您不想公开您的应用程序如何工作的细节。最好的情况是这对他们毫无意义;最坏的情况是它帮助恶意用户了解您的系统。
【解决方案2】:

一个。在控制器(或其他任何地方)中不实现任何类型的 try catch 并让 Elmah 处理异常的正确方法是什么?

我会说 Elmah 不会“处理”异常,它会记录它们。理想情况下,您应该尝试处理错误 - 一定要记录它们,但还要添加处理它们的逻辑,这样它们就不会中断用户的工作流程。

我会将逻辑包装在 try 块中,并在 catch 使用

Elmah.ErrorSignal.FromCurrentContext().Raise(exception);

记录任何出错的地方。然而,紧接着该行之后,我会做一些事情来尝试从异常中恢复 - 捕获特定的异常类型,而不仅仅是catch (Exception e),并在记录它们后处理它们。这个想法是,您应该检查您的日志,找出导致异常的原因,并改进您的程序,使其不再引发异常。

要显示您自己的错误页面,可以使用HandleErrorAttribute,或者如果您不想使用它,还可以使用控制器的OnException() 方法,当控制器操作方法因异常退出而不是完成时调用该方法一般。 ExceptionContext 对象被传递到该方法中,因此您可以使用它来获取引发的异常并记录它,进行可能需要的任何清理等。

【讨论】:

  • 请在我发布给我自己的问题的答案中评论我的方法。谢谢
【解决方案3】:

我知道我参加聚会很晚了,但我在谷歌搜索类似的东西时偶然发现了这个答案。

我不喜欢在我的代码中到处使用 try catch 块,尤其是在网络应用程序中。我让 Elmah 捕获所有内容并将其记录在幕后。然后在 web.config 文件中可以根据错误类型重定向...

 <customErrors mode="RemoteOnly" defaultRedirect="~/Error" >
  <error statusCode="500" redirect="~/Error"/>
  <error statusCode="404" redirect="~/NotFound"/>
</customErrors>

【讨论】:

    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    相关资源
    最近更新 更多