ASP.MVC中的HandleError和强类型布局

时间:2014-10-14 11:05:31

标签: c# asp.net-mvc asp.net-mvc-4

我正在使用ASP.MVC 4.我有一个强类型布局,它连接到基本视图模型(每个其他视图模型都继承自基本视图模型)。我正在尝试使用标准HandleError过滤器处理错误。它是开箱即用配置的,如果布局没有强类型,则可以正常工作。

我的示例例外如下:

public class TestController : Controller
{
    public ActionResult Index()
    {
        throw new Exception("oops");
    }
}

当机制试图将错误页面插入强类型布局时,它会遇到麻烦,因为它没有模型。

有谁知道在HandleError过滤器中使用强类型布局的情况是什么?在抛出异常之前是否有可能为布局设置模型?

编辑:

可能的解决方案是关闭标准错误处理机制并捕获Global.asax中Application_Error方法中的异常。您可以在此处找到示例解决方案:ASP.MVC HandleError attribute doesn't work

无论如何 - 如果有人有其他解决方案,请发布。

3 个答案:

答案 0 :(得分:4)

您可以编写自己的HandleError属性并在FilterConfig上注册,而不是默认属性。您的自定义属性将扩展默认属性,覆盖结果,以便传递给视图的模型实例具有所需类型:

public class CustomHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        //When already handled, do nothing
        if (context.ExceptionHandled)
            return;

        //Run the base functionality
        base.OnException(context);

        //If the base functionality didnt handle the exception, then exit (as the exception is not of the type this filter should handle)
        if (!context.ExceptionHandled) return;

        //Set a view as the result           
        context.Result = GetViewResult(context);            
    }

    private ViewResult GetViewResult(ExceptionContext context)
    {
        //The model of the error view (YourModelType) will inherit from the base view model required in the layout
        YourModelType model = new YourModelType(context.Exception, ...);
        var result = new ViewResult
        {
            ViewName = View,
            ViewData = new ViewDataDictionary<YourModelType>(model),
            TempData = context.Controller.TempData
        };
        return result;
    }
}

然后全局注册此过滤器而不是默认的HandleErrorAttribute

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new CustomHandleErrorAttribute());
    ...
}

答案 1 :(得分:1)

我能想到的只有

  • a)在Global.asax.cs中,处理Application_Error(或 Application_OnError,签名现在让我逃避)并重定向到 强类型视图
  • b)编辑web.config customErrors部分以指向您的强项 打字视图。然而,做b)可能是其他人已经发现的,例如 benfoster.io/blog/aspnet-mvc-custom-error-pages

答案 2 :(得分:0)

您可以通过执行以下操作来获取重现错误的控制器名称和操作名称:

public class CustomErrorException: HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        filterContext.Result = new ViewResult {
            ViewName = "CustomError",
            ViewData = new ViewDataDictionary<HandleErrorInfo> { 
                Model = new HandleErrorInfo(
                    exception: filterContext.Exception,
                    controllerName: filterContext.RequestContext.RouteData.Values["controller"].ToString(),
                    actionName: filterContext.RequestContext.RouteData.Values["action"].ToString()
                ) 
            }
        };

        //You can log your errors here.
        filterContext.ExceptionHandled = true;
    }
}

在“CustomError.cshtml”视图中,您可以这样做:
@model HandleErrorInfo
嘿,这是一个自定义错误!
控制器名称:@ Model.ControllerName
动作名称:@ Model.ActionName
异常消息:@ Model.Exception.Message