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

C# 在MVC4中的自定义错误页上显示错误消息,c#,asp.net-mvc-4,C#,Asp.net Mvc 4,我有一个MVC4 ASP.NET应用程序,希望构建一个自定义错误页面来处理可能发生的任何错误,因此没有人会遇到神秘的错误消息,只有一个“Oops,this shouldnt have haven”页面,上面有导航栏 但是,为了帮助定位错误,我想在错误页面中添加一个字段,显示发生的错误 My Web.config包含: <customErrors mode="On" defaultRedirect="~/Error"> </customErrors> 当我输入无效路径(

我有一个MVC4 ASP.NET应用程序,希望构建一个自定义错误页面来处理可能发生的任何错误,因此没有人会遇到神秘的错误消息,只有一个“Oops,this shouldnt have haven”页面,上面有导航栏

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

My Web.config包含:

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

</customErrors>

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

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

另外,请记住,您在这里呈现的消息对用户来说仍然可能是神秘的,因为他们通常不是开发人员本身。而且,即使他们确实理解了这一点,他们仍然无能为力。此外,您可能会在错误消息中传递有关服务器的信息,这是您不希望公众知道的

最好的做法总是捕获异常并从中恢复。例如,如果用户提出了错误的请求,而不是返回400,则返回视图时会显示一条消息,告诉用户他们做错了什么以及如何恢复。如果这是一个您确实无法恢复的错误,那么只需向用户道歉并记录错误,以便通知您的开发团队修复它。在这种情况下,准确地告诉用户出了什么问题是毫无意义的,因为,同样地,他们将无力自行纠正错误

编辑


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

我建议您实现从
控制器继承的
BaseController
,并在那里重写
OneException(ExceptionContext filterContext)
。然后所有其他控制器将从
BaseController
继承,并在
Exception
上重定向到错误页面

 <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页


404找不到
public class ErrorController : Controller
{
    //
    // GET: /Views/Error/

    public ActionResult Index()
    {
        var error = Server.GetLastError();
        ViewBag.ErrorMessage = error == null ? "" : error.Message;
        return View();
    }
}
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;
        }
 <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>
   <%
    Server.ClearError();
Response.Status = "404 Not Found";
Response.StatusCode = 404;
         %>
    <div>
    <h2>404 Not Found</h2>
    </div>