2

我在处理 MVC 中的错误时遇到问题。我的目标是在标题中显示“友好”错误消息,但应用程序应该已经可见。我在基本控制器方法上使用覆盖 OnException,如下所示:

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")?v=@Html.Action("GetVersion", "Main")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/Worklist.css")?v=@Html.Action("GetVersion", "Main")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/jquery.contextMenu.css")?v=@Html.Action("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 错误。

谢谢你的帮助。

4

1 回答 1

2

在您的web.config中,确保您具有以下配置:

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

的默认值为errorMode( docsDetailedLocalOnly )

于 2013-10-29T16:26:02.093 回答