在MVC4中的自定义错误页面上显示错误消息

时间:2015-01-27 13:35:58

标签: c# asp.net-mvc-4

我有一个MVC4 ASP.NET应用程序,并希望构建一个自定义错误页面来处理可能发生的任何错误,因此没有人会面对一个神秘的错误消息,只有“哎呀,这不应该发生”页面,顶部的导航栏。

但是,为了帮助找到错误,我想在错误页面中添加一个字段,显示发生的错误。

我的Web.config包含:

<customErrors mode="On" defaultRedirect="~/Error">

</customErrors>

错误看起来像这样:

@{
    ViewBag.Title = "Error Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Uups, an error occured</h2>
<p>This should not have happened. Enjoy this error page instead.</p>
<pre>
    @ViewBag.ErrorMessage
</pre>

错误控制器是这样的:

public class ErrorController : Controller
{
    //
    // GET: /Views/Error/

    public ActionResult Index()
    {
        var error = Server.GetLastError();
        ViewBag.ErrorMessage = error == null ? "" : error.Message;
        return View();
    }
}

当我输入无效路径(发生404错误)时,错误控制器中的错误变量为“null”,因此不会显示错误,但会显示错误页面。我做错了什么?

3 个答案:

答案 0 :(得分:1)

错误页面是一个单独的响应周期。因此,您在原始操作中设置的任何内容(例如ViewBag)都会消失。您需要在TempData之类的内容中设置错误消息,或者将其记录在错误页面上可以检索的位置。但是,无论使用哪种方法,请注意您无法在错误页面上生成异常。否则,您将以无限重定向周期发送用户。因此,通常最好保持错误页面简单,以避免引起任何其他异常。

另外,请记住,您在此处展示的消息仍然可能对用户来说很神秘,因为他们通常不会是开发人员。而且,即使他们 了解它,他们仍然无能为力。此外,您可能会在错误消息中传递有关您的服务器的信息,而这些信息是您不希望公众了解的。

最好的做法是始终捕捉异常并从中恢复。例如,如果用户发出错误请求,而不是返回400,则返回视图,并显示一条消息,告诉用户他们做错了什么以及如何恢复。如果这是您无法恢复的错误,那么,只需向用户道歉并记录错误,以便通知您的开发团队修复它。在这个场景中告诉用户到底出了什么问题真的没有意义,因为再次,他们自己无法纠正它。

修改

由于您的问题专门提到404,最好的办法就是创建一个特定的404错误页面。从这个错误中你可以合理地做的就是告诉用户无法找到页面,然后你的404可以提供一些有用的链接或站点地图来帮助用户恢复。试图只有一个错误页面而不是处理任何响应会增加复杂性,这也增加了从错误页面本身触发异常的可能性(同样,巨大的禁忌)。

答案 1 :(得分:1)

我建议你实施BaseController来继承自Controller并在那里覆盖OnException(ExceptionContext filterContext)。然后所有其他控制器将从BaseController继承而在Exception,您将重定向到您的错误页面。

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

            filterContext.Result = new ViewResult
            {
                ViewName = "~/Error.cshtml",
                ViewData = new ViewDataDictionary {{"Exception", filterContext.Exception.Message}}
            };

            filterContext.ExceptionHandled = true;
        }

答案 2 :(得分:0)

 <customErrors mode="On" defaultRedirect="~/Error/Error.html" redirectMode="ResponseRewrite">
      <error redirect="~/Error/404.aspx" statusCode="404" />
      <error redirect="~/Error/403.aspx" statusCode="403" />
      <error redirect="~/Error/500.html" statusCode="500" />
    </customErrors>

在根目录“Error”

中创建页面404.aspx
   <%
    Server.ClearError();
Response.Status = "404 Not Found";
Response.StatusCode = 404;
         %>
    <div>
    <h2>404 Not Found</h2>
    </div>