c# - MVC 4 中的自定义错误

标签 c# asp.net-mvc asp.net-mvc-4 error-handling

我在处理 MVC 中的错误时遇到问题。我的目标是在标题中显示“友好”错误消息,但应用程序应该已经可见。 我在基本 Controller 方法上使用重写 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);
}

我调用我的 View

@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")<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="28175e1568605c454406694b5c414746" rel="noreferrer noopener nofollow">[email protected]</a>("GetVersion", "Main")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/Worklist.css")<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="aa95dc97eae2dec7c684ebc9dec3c5c4" rel="noreferrer noopener nofollow">[email protected]</a>("GetVersion", "Main")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/jquery.contextMenu.css")<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="053a7338454d7168692b4466716c6a6b" rel="noreferrer noopener nofollow">[email protected]</a>("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 而不是我的错误 View 。那么我如何修改代码以避免错误 500 并在自定义显示中捕获错误(服务器无法修改,但我可以使用 web.config)?如果我评论 ControllerContext.HttpContext.Response.StatusCode = 500;在 DisplayError 中,未捕获 Ajax 错误。

感谢您的帮助。

最佳答案

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

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

errorMode 的默认值为 DetailedLocalOnly ( docs )

关于c# - MVC 4 中的自定义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19663773/

相关文章:

c# - 如何根据在 ASP.NET MVC 中单击的按钮更改表单提交的操作?

jquery - 折叠和展开列表

c# - 为什么 "null"出现在 C# 和 Java 中?

c# - 如何重用相似但不同的类属性

c# - Protocol Buffer .net "The type cannot be changed once a serializer has been generated"

c# - MVC 3 表单例份验证 User.Identity.Name 返回 false

c# - 将 MVC 1 应用程序部署到远程服务器时 Global.asax 解析器错误

c# - 正则表达式 c# 从 <a> 标签中提取 url

asp.net - ASP.NET MVC 4自定义错误 View 问题

asp.net - 使用HttpRequestMessage.Properties承载每个请求的上下文