如何使自定义错误页在ASP.NET MVC 4中工作

Wat*_* v2 242 asp.net asp.net-mvc asp.net-mvc-4

我想要显示500,404和403的自定义错误页面.这是我所做的:

  1. 在web.config中启用了自定义错误,如下所示:

    <customErrors mode="On" 
                  defaultRedirect="~/Views/Shared/Error.cshtml">
    
        <error statusCode="403" 
               redirect="~/Views/Shared/UnauthorizedAccess.cshtml" />
    
        <error statusCode="404" 
               redirect="~/Views/Shared/FileNotFound.cshtml" />
    
    </customErrors>
    
    Run Code Online (Sandbox Code Playgroud)
  2. HandleErrorAttributeFilterConfig类中注册为全局动作过滤器,如下所示:

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomHandleErrorAttribute());
        filters.Add(new AuthorizeAttribute());
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 为上述每条消息创建了自定义错误页面.500的默认值已经开箱即用.

  4. 在每个自定义错误页面视图中声明该页面的模型 System.Web.Mvc.HandleErrorInfo

对于500,它显示自定义错误页面.对于其他人,它没有.

有什么我想念的吗?

看起来这并不是显示自定义错误的全部内容,因为我OnExceptionHandleErrorAttribute类的方法中读取代码并且它只处理500.

我该怎么做才能处理其他错误?

Pab*_*meo 346

我目前的设置(在MVC3上,但我认为它仍然适用)依赖于拥有ErrorController,所以我使用:

<system.web>
    <customErrors mode="On" defaultRedirect="~/Error">
      <error redirect="~/Error/NotFound" statusCode="404" />
    </customErrors>
</system.web>
Run Code Online (Sandbox Code Playgroud)

控制器包含以下内容:

public class ErrorController : Controller
{
    public ViewResult Index()
    {
        return View("Error");
    }
    public ViewResult NotFound()
    {
        Response.StatusCode = 404;  //you may want to set this to 200
        return View("NotFound");
    }
}
Run Code Online (Sandbox Code Playgroud)

而观点就是你实现它们的方式.我倾向于添加一些逻辑,以显示应用程序处于调试模式时的堆栈跟踪和错误信息.所以Error.cshtml看起来像这样:

@model System.Web.Mvc.HandleErrorInfo
@{
    Layout = "_Layout.cshtml";
    ViewBag.Title = "Error";
}
<div class="list-header clearfix">
    <span>Error</span>
</div>
<div class="list-sfs-holder">
    <div class="alert alert-error">
        An unexpected error has occurred. Please contact the system administrator.
    </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>
            <div style="overflow:scroll">
                <pre>
                    @Model.Exception.StackTrace
                </pre>
            </div>
        </div>
    }
</div>
Run Code Online (Sandbox Code Playgroud)

  • 对于其他任何发现这有用的人,但需要更多背景; <customErrors>标记位于web.config中的<system.web>内. (53认同)
  • 请为上帝的爱而忽略评论说"你可能想在代码中将其设置为200".不要那样做! (38认同)
  • 根据我的经验,控制器中的代码似乎没有执行.MVC4 - 在不同的控制器中抛出System.Exception将使Error.cshtml文件呈现,但不通过ErrorController.有没有其他人经历过这个? (11认同)
  • 您是否必须在Global.asax中的Application_Error中为此Pablo添加任何内容? (7认同)
  • **其他人的更新** - 显然我的问题正在发生,因为我在`CustomerErrors`元素上有`redirectMode ="ResponseRewrite"` (7认同)
  • 这不需要任何额外的步骤......事实上,Error.cshtml应该已经存在于Views/Shared中,所以只需将其编辑为上面的内容即可. (4认同)
  • 我应该补充一点,上面的注释只有在`RegisterGlobalFilters()中出现`filters.Add(new HandleErrorAttribute())`时才会出现. (2认同)
  • 我也收到了这个错误.当我发现为什么它不起作用时我就要自杀了.我忘记了我正在使用Authorize过滤器属性,因此如果您正在使用此属性,请不要忘记在错误操作中添加[AllowAnonymous]. (2认同)
  • 任何人犯了我做的错误 - 这段代码假设它与_Layout.cshtml文件在同一路径中.你需要改变@ {Layout ="〜/ Views/Shared/_Layout.cshtml"; (2认同)
  • 为我放置response.statuscode使它转到默认的ASP.NET 404错误页面.我完全复制了这个答案.我想知道是否还有其他需要改变的设置.如果我删除response.status代码一切正常.我不确定我是否需要状态代码,但我想知道浏览器是否需要它或其他东西. (2认同)
  • System.Web.Mvc.HandleErrorInfo 模型为 NULL! (2认同)
  • 如果在返回错误响应之前没有执行重定向到错误页面URL,那将会很好.这不是大多数Web服务器所期望的. (2认同)

Mac*_*gon 39

我已经完成了pablo解决方案而且我总是遇到错误(MVC4)

未找到视图"错误"或其主控,或者没有视图引擎支持搜索的位置.

要摆脱这一点,删除该行

 filters.Add(new HandleErrorAttribute());
Run Code Online (Sandbox Code Playgroud)

在FilterConfig.cs中


cod*_*pro 23

我做的事情需要的代码少于发布的其他解决方案.

首先,在我的web.config中,我有以下内容:

<customErrors mode="On" defaultRedirect="~/ErrorPage/Oops">
   <error redirect="~/ErrorPage/Oops/404" statusCode="404" />
   <error redirect="~/ErrorPage/Oops/500" statusCode="500" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)

控制器(/Controllers/ErrorPageController.cs)包含以下内容:

public class ErrorPageController : Controller
{
    public ActionResult Oops(int id)
    {
        Response.StatusCode = id;

        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,视图包含以下内容(为简单起见,它被删除,但它可以包含:

@{ ViewBag.Title = "Oops! Error Encountered"; }

<section id="Page">
  <div class="col-xs-12 well">
    <table cellspacing="5" cellpadding="3" style="background-color:#fff;width:100%;" class="table-responsive">
      <tbody>
        <tr>
          <td valign="top" align="left" id="tableProps">
            <img width="25" height="33" src="~/Images/PageError.gif" id="pagerrorImg">
          </td>
          <td width="360" valign="middle" align="left" id="tableProps2">
            <h1 style="COLOR: black; FONT: 13pt/15pt verdana" id="errortype"><span id="errorText">@Response.Status</span></h1>
          </td>
        </tr>
        <tr>
          <td width="400" colspan="2" id="tablePropsWidth"><font style="COLOR: black; FONT: 8pt/11pt verdana">Possible causes:</font>
          </td>
        </tr>
        <tr>
          <td width="400" colspan="2" id="tablePropsWidth2">
            <font style="COLOR: black; FONT: 8pt/11pt verdana" id="LID1">
                            <hr>
                            <ul>
                                <li id="list1">
                                    <span class="infotext">
                                        <strong>Baptist explanation: </strong>There
                                        must be sin in your life. Everyone else opened it fine.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Presbyterian explanation: </strong>It's
                                        not God's will for you to open this link.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong> Word of Faith explanation:</strong>
                                        You lack the faith to open this link. Your negative words have prevented
                                        you from realizing this link's fulfillment.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Charismatic explanation: </strong>Thou
                                        art loosed! Be commanded to OPEN!<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Unitarian explanation:</strong> All
                                        links are equal, so if this link doesn't work for you, feel free to
                                        experiment with other links that might bring you joy and fulfillment.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Buddhist explanation:</strong> .........................<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Episcopalian explanation:</strong>
                                        Are you saying you have something against homosexuals?<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Christian Science explanation: </strong>There
                                        really is no link.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Atheist explanation: </strong>The only
                                        reason you think this link exists is because you needed to invent it.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Church counselor's explanation:</strong>
                                        And what did you feel when the link would not open?
                                    </span>
                                </li>
                            </ul>
                            <p>
                                <br>
                            </p>
                            <h2 style="font:8pt/11pt verdana; color:black" id="ietext">
                                <img width="16" height="16" align="top" src="~/Images/Search.gif">
                                HTTP @Response.StatusCode - @Response.StatusDescription <br>
                            </h2>
                        </font>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</section>
Run Code Online (Sandbox Code Playgroud)

就这么简单.它可以很容易地扩展,以提供更详细的错误信息,但ELMAH为我处理,statusCode和statusDescription是我通常需要的.


max*_*pan 12

我建议使用Global.asax.cs文件.

 protected void Application_Error(Object sender, EventArgs e)
{
    var exception = Server.GetLastError();
    if (exception is HttpUnhandledException)
    {
        Server.Transfer("~/Error.aspx");
    }
    if (exception != null)
    {
        Server.Transfer("~/Error.aspx");
    }
    try
    {
        // This is to stop a problem where we were seeing "gibberish" in the
        // chrome and firefox browsers
        HttpApplication app = sender as HttpApplication;
        app.Response.Filter = null;
    }
    catch
    {
    }
}
Run Code Online (Sandbox Code Playgroud)


Vic*_*ber 10

这里似乎有许多步骤混杂在一起.我会提出我从头开始做的事情.

  1. 创建ErrorPage控制器

    public class ErrorPageController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public ActionResult Oops(int id)
        {
            Response.StatusCode = id;
            return View();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 添加这两个操作的视图(右键单击 - >添加视图).这些应出现在名为ErrorPage的文件夹中.

  3. 在里面App_Start打开FilterConfig.cs并注释掉错误处理过滤器.

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        // Remove this filter because we want to handle errors ourselves via the ErrorPage controller
        //filters.Add(new HandleErrorAttribute());
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在web.config里面添加以下<customerErrors>条目System.Web

    <customErrors mode="On" defaultRedirect="~/ErrorPage/Oops">
        <error redirect="~/ErrorPage/Oops/404" statusCode="404" />
        <error redirect="~/ErrorPage/Oops/500" statusCode="500" />
    </customErrors>
    
    Run Code Online (Sandbox Code Playgroud)
  5. 测试(当然).在代码中抛出未处理的异常并看到它转到ID为500的页面,然后使用URL到不存在的页面以查看404.


小智 6

在maxspan发布的答案的基础上,我在GitHub上整理了一个最小的示例项目,展示了所有工作部分.

基本上,我们只是Application_Errorglobal.asax.cs添加一个方法来拦截异常,并让我们有机会将(或更准确地说,转移请求)重定向到自定义错误页面.

    protected void Application_Error(Object sender, EventArgs e)
    {
        // See http://stackoverflow.com/questions/13905164/how-to-make-custom-error-pages-work-in-asp-net-mvc-4
        // for additional context on use of this technique

        var exception = Server.GetLastError();
        if (exception != null)
        {
            // This would be a good place to log any relevant details about the exception.
            // Since we are going to pass exception information to our error page via querystring,
            // it will only be practical to issue a short message. Further detail would have to be logged somewhere.

            // This will invoke our error page, passing the exception message via querystring parameter
            // Note that we chose to use Server.TransferRequest, which is only supported in IIS 7 and above.
            // As an alternative, Response.Redirect could be used instead.
            // Server.Transfer does not work (see https://support.microsoft.com/en-us/kb/320439 )
            Server.TransferRequest("~/Error?Message=" + exception.Message);
        }

    }
Run Code Online (Sandbox Code Playgroud)

错误控制器:

/// <summary>
/// This controller exists to provide the error page
/// </summary>
public class ErrorController : Controller
{
    /// <summary>
    /// This action represents the error page
    /// </summary>
    /// <param name="Message">Error message to be displayed (provided via querystring parameter - a design choice)</param>
    /// <returns></returns>
    public ActionResult Index(string Message)
    {
        // We choose to use the ViewBag to communicate the error message to the view
        ViewBag.Message = Message;
        return View();
    }

}
Run Code Online (Sandbox Code Playgroud)

错误页面查看:

<!DOCTYPE html>

<html>
<head>
    <title>Error</title>
</head>
<body>

    <h2>My Error</h2>
    <p>@ViewBag.Message</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

除了filters.Add(new HandleErrorAttribute())FilterConfig.cs中禁用/删除之外,不涉及任何其他内容

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //filters.Add(new HandleErrorAttribute()); // <== disable/remove
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然实现起来非常简单,但我在这种方法中看到的一个缺点是使用查询字符串将异常信息传递到目标错误页面.