关于c#:HandleError和ASP.MVC中的强类型布局

HandleError and strongly typed layout in ASP.MVC

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

我的示例例外如下:

1
2
3
4
5
6
7
public class TestController : Controller
{
    public ActionResult Index()
    {
        throw new Exception("oops");
    }
}

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

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

编辑:

可能的解决方案是关闭标准错误处理机制并捕获Global.asax中Application_Error方法中的异常。您可以在此处找到示例解决方案:ASP.MVC HandleError属性不起作用

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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

1
2
3
4
5
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new CustomHandleErrorAttribute());
    ...
}


我能想到的唯一方法就是

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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