我正在使用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
无论如何 - 如果有人有其他解决方案,请发布。
答案 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)
我能想到的只有
答案 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