【问题标题】:Is there a good way to handle exceptions in MVC ChildActions有没有处理 MVC ChildActions 中异常的好方法
【发布时间】:2014-08-19 00:49:56
【问题描述】:

我似乎在使用 Child Actions 吞下很多异常。

    [ChildActionOnly]
    [OutputCache(Duration = 1200, VaryByParam = "key;param")]
    public ActionResult ChildPart(int key, string param)
    {
        try
        {
            var model = DoRiskyExceptionProneThing(key, param)
            return View("_ChildPart", model);
        }
        catch (Exception ex)
        {
            // Log to elmah using a helper method
            ErrorLog.LogError(ex, "Child Action Error ");

            // return a pretty bit of HTML to avoid a whitescreen of death on the client
            return View("_ChildActionOnlyError");
        }
    }

我觉得我在剪切和粘贴成堆的代码,每次剪切粘贴我们都知道一只小猫正被天使的眼泪淹没。

是否有更好的方法来管理子操作中的异常,以允许屏幕的其余部分正确呈现?

【问题讨论】:

  • 你在这里发现了什么样的异常?
  • 任何异常,我继承了一些非常丑陋的代码。问题是,如果子操作中没有捕获异常,则整个屏幕都不会呈现。我能够让事情以这种方式运行并收集有关引发异常的证据。大多数例外似乎是数据丢失之类的。
  • 我会考虑在自定义操作过滤器中执行这些操作,该过滤器可以与您的所有操作共享。
  • 那么如何将我的操作方法逻辑包装在操作过滤器中?
  • Rvan 的回答使用了一种动作过滤器。

标签: c# asp.net-mvc child-actions


【解决方案1】:

您可以基于 Mvc 的 HandleError 属性创建 CustomHandleError 属性,覆盖 OnException 方法,进行日志记录并可能返回自定义视图。

public override void OnException(ExceptionContext filterContext)
{
    // Log to elmah using a helper method
    ErrorLog.LogError(filterContext.Exception, "Oh no!");

    var controllerName = (string)filterContext.RouteData.Values["controller"];
    var actionName = (string)filterContext.RouteData.Values["action"];

    if (!filterContext.HttpContext.IsCustomErrorEnabled)
    {
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = 500;
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
        filterContext.Result = new ViewResult
        {
            ViewName = "_ChildActionOnlyError",
            MasterName = Master,
            ViewData = new ViewDataDictionary(model),
            TempData = filterContext.Controller.TempData
        };
        return;
    }
}

然后使用此逻辑装饰您想要启用的任何控制器和/或操作,如下所示:

[ChildActionOnly]
[OutputCache(Duration = 1200, VaryByParam = "key;param")]
[CustomHandleError]
public ActionResult ChildPart(int key, string param)
{
    var model = DoRiskyExceptionProneThing(key, param)
    return View("_ChildPart", model);
}

【讨论】:

  • 这一行 'filterContext.HttpContext.IsCustomErrorEnabled' 检查什么?
  • 如果您有自定义错误 RemoteOnly(并且您在本地访问应用程序)或 Off,则此属性设置为 false。这样可以防止向公众显示敏感信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-08
  • 1970-01-01
  • 2014-08-26
相关资源
最近更新 更多