MVC4的自定义错误

时间:2014-02-20 14:04:54

标签: c# asp.net-mvc asp.net-mvc-4 custom-error-pages

我想用我自己的模型为我的MVC4项目创建一个自定义错误页面。

我使用了来自Custom error pages on asp.net MVC3

的Darin Dimitrov的方法

现在我想使用我自己的(测试)模型:

public class ErrorModel
{
    public string message { get; set; }
}

现在当我使用customErrors mode =“Off”时,一切正常但只能在本地机器上运行。当我从远程计算机访问计算机时,会显示默认错误。 (这是预期的方式 - 我猜)

现在,当我设置系统突然期望他自己的模型而不是我的时候:

“传递到字典中的模型项的类型为'System.Web.Mvc.HandleErrorInfo',但此字典需要类型为'Project.Controllers.ErrorModel'的模型项。

当模式为Off时,如何强制系统通过customErrors =“Off”向远程系统显示页面,或者如何强制他使用我的模型而不是HandleErrorInfo模型?

My ErrorController

public class ErrorController : Controller
{
  public ActionResult General(Exception exception)
  {
      var viewModel = new ErrorModel()
      {
          message = exception.Message          
      };
      return View(viewModel);
}

观点:

@model SRMv2.WebUI.Controllers.ErrorModel
@{
}
@Html.Raw(Model.message)

在Global.asax

protected void Application_Error()
{
    HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
    HttpContext.Current.Response.Cache.SetValidUntilExpires(false);          HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Cache.SetNoStore();

    var exception = Server.GetLastError();
    var httpException = exception as HttpException;
    Response.Clear();
    Server.ClearError();
    var routeData = new RouteData();
    routeData.Values["controller"] = "Errors";
    routeData.Values["action"] = "General";
    routeData.Values["exception"] = exception;
    Response.StatusCode = 500;
    if (httpException != null)
    {
       Response.StatusCode = httpException.GetHttpCode();
       switch (Response.StatusCode)
       {
          case 403:
            routeData.Values["action"] = "Http403";
            break;
          case 404:
            routeData.Values["action"] = "Http404";
            break;
        }
     }

   IController errorController = new ErrorController();
   var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
   errorController.Execute(rc);
}

2 个答案:

答案 0 :(得分:1)

发生的事情是您的错误处理代码抛出了未处理的异常,然后由默认的aspnet处理程序捕获。没有实际看到你用来渲染错误页面的视图,我假设你没有更改那里的模型类型以匹配控制器中的模型集。

答案 1 :(得分:0)

maf748你的答案完全正确。有趣的是它发生的原因。

当customError为Off时,MVC框架调用global.asax中的Application_Error(),调用ErrorController(参见问题)。 当你将customError切换为On时,MVC框架会说,很好用户处理Exception,找到View并呈现它,而不正确调用ErrorController。所以他无法渲染视图模型,并使用了默认的viewModel(System.Web.Mvc.HandleErrorInfo)。

因此视图不匹配,框架引发了Application_Error()和Server.GetLastError()返回的视图模型不匹配...这是正确的,然后生成ErrorController / View并出现此错误。 ..

那么我的解决方案呢?

调用ErrorController OnActionExecuted()

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

        if (filterContext.Exception != null)
        {
            filterContext.ExceptionHandled = true;
            IController errorController = new ErrorController();
            var routeData = new RouteData();
            routeData.Values["controller"] = "Errors";
            routeData.Values["action"] = "General";
            routeData.Values["exception"] = filterContext.Exception;

            var rc = new RequestContext(filterContext.HttpContext, routeData);
            errorController.Execute(rc);
        }

再次感谢您让我走上正轨,因为所描述的大部分内容都隐藏在框架之后。