2013-10-29 46 views
2

我在处理MVC错误时遇到了问题。我的目标是在标题中显示“友好”的错误消息,但应用程序应该已经可见。 我使用本体控制器方法倍率onException的如下:MVC中的自定义错误4

protected override void OnException(ExceptionContext filterContext) 
{ 
    if (filterContext.ExceptionHandled) 
     return; 

    var error = new ErrorModel(filterContext.Exception); 
    error.ActionName = filterContext.RouteData.Values["action"].ToString(); 
    error.ControllerName = filterContext.RouteData.Values["controller"].ToString(); 

    filterContext.Controller.TempData["ErrorInfo"] = error; 

    filterContext.HttpContext.Response.Clear(); 
    filterContext.HttpContext.Response.StatusCode = 500; 
    filterContext.ExceptionHandled = true; 
    filterContext.Result = this.RedirectToAction(actionName: "DisplayError", controllerName: "Error");    

    //base.OnException(filterContext); 
} 

ErrorModel是HandleErrorInfo的平坦副本,因为所有的动作需要被序列化。

在ErrorController,我找回我的模型从TempData的

public ActionResult DisplayError() 
{ 
    var error = TempData["ErrorInfo"] as ErrorModel; 
    ControllerContext.HttpContext.Response.StatusCode = 500; 

    return PartialView("Error", error); 
} 

,我打电话给我的查看

@using log4net; 
@model Easily.MVC.Utils.ErrorModel 
@{ 
    ViewBag.Title = "Error"; 
} 

    <link href="@string.Format("http://{0}/easily.Ressources.Web/css/easilyCommon.min.css", System.Configuration.ConfigurationManager.AppSettings["EasilyServerName"])" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/custom.css")[email protected]("GetVersion", "Main")" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/Worklist.css")[email protected]("GetVersion", "Main")" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/jquery.contextMenu.css")[email protected]("GetVersion", "Main")" rel="stylesheet" type="text/css" /> 
    <script type="text/javascript"> window['currentPath'] = '@Url.Content("~/")'; </script> 
    <script src="@string.Format("http://{0}/easily.Ressources.Web/js/easilyCommon.min.js", System.Configuration.ConfigurationManager.AppSettings["EasilyServerName"])" type="text/javascript"></script> 

<fieldset class="divError"> 
    @if (ViewBag != null && ViewBag.Message != null) 
    { 
     <legend title="Erreur Easily.MVC" class="legendError">Une erreur s'est produite</legend>@* 
     <span>Erreur Easily.MVC</span>*@ 
    } 
    @if (Model != null /*&& HttpContext.Current.IsDebuggingEnabled*/) 
    { 
     <legend title="Erreur @Model.Exception.Message" class="legendError">Une erreur s'est produite</legend>@* 
     <span>Erreur @Model.Exception.Message</span>*@ 
    } 

    <div class="detailError"> 
     <h3>Detail de l'erreur</h3> 
     <div class="list-sfs-holder msgError"> 
      @if (ViewBag != null && ViewBag.Message != null) 
      { 
       <div class="alert alert-error">@ViewBag.Message</div> 
      } 
      @if (Model != null /*&& HttpContext.Current.IsDebuggingEnabled*/) 
      { 
       <div> 
        <p> 
         <b>Exception:</b> @Model.Exception.Message<br /> 
         <b>Controller:</b> @Model.ControllerName<br /> 
         <b>Action:</b> @Model.ActionName 
        </p> 
        <hr /> 
        <p> 
         <b>StackTrace:</b> 
        </p> 
        <div style="overflow: scroll; width: 980px;"> 

          <pre> 
         @Model.Exception.StackTrace 
       </pre> 

        </div> 
       </div> 
      } 

     </div> 
    </div> 
</fieldset> 

@{ 
    ILog log = LogManager.GetLogger("WorkListError"); 

    if (ViewBag != null && ViewBag.Message != null) 
    { 
     log.Error("ViewBag.Message:" + @ViewBag.Message); 
    } 
    if (Model != null && HttpContext.Current.IsDebuggingEnabled) 
    { 
     log.Error("Exception:" + Model.Exception.Message + "|" + 
        "Controller:" + Model.ControllerName + "|" + 
        "Action:" + Model.ActionName + "|" + 
        "StackTrace:" + Model.Exception.StackTrace 
       ); 
    }  
} 

<script> 

    $(document).ready(function() { 
     $(".detailError").accordion({ collapsible: true, active: false, heightStyle: "content", width: '980px' }); 
    }); 

</script> 

至少,AJAX错误,我使用这个脚本:

$(document).ajaxError(function (event, jqxhr, settings, exception) { 
    $("#error_content").html(jqxhr.responseText); 
}); 

使用此代码,结果是我的目标@ localhost。但是当我在测试服务器上部署它时,我的服务器消息错误500而不是我的错误视图。所以我如何修改代码以避免错误500并且在自定义显示中捕获错误(服务器无法修改,但我可以使用web.config)?如果我评论ControllerContext.HttpContext.Response.StatusCode = 500;在DisplayError中,Ajax错误没有被捕获。

感谢您的帮助。

+0

我不知道这是否回答您的问题(可能没有按” t),但你可以(也应该在我看来)返回一个状态码500和错误视图,而不是重定向到一个错误页面。这使得事情变得更清晰,更易于调试并且易于实现。 – acfrancis

+0

另外,你应该在控制器内使用你的日志库,而不是在视图内部。 –

+0

是的,你是对的。 ErrorController和BaseController在单独的通用dll中。视图是在使用dll的项目中。下一步是在此dll中集成View并从此dll进行日志记录。但它会在另一个StackOverflow问题;) –

回答

2

在你web.config,请确保您有以下配置:

<configuration> 
    <system.webServer> 
     <httpErrors errorMode="Detailed" /> 
    </system.webServer> 
</configuration> 

errorMode的默认值是DetailedLocalOnlydocs

+0

这只是完美的,谢谢:) –