如何将服务器错误的 http 状态代码捕获到 ASP.NET MVC 中的通用自定义错误视图中 [英] How do I catch the http status code of server errors into a generic custom error view in ASP.NET MVC

查看:16
本文介绍了如何将服务器错误的 http 状态代码捕获到 ASP.NET MVC 中的通用自定义错误视图中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 ASP.NET MVC 4 中实现一个通用的自定义错误页面.我基本上设置了一个错误布局,它定义了一个部分,用于输出响应的 http 状态码.

我希望我的错误最终出现的视图继承了这样的布局,并简单地添加了来自其模型的消息,该消息被实例化并在控制器中对 View() 的调用中传递(名为错误")我在 web.config 中设置为处理自定义错误.

</customErrors>

自定义错误控制器:

公共类 ErrorController : 控制器{公共 ActionResult 索引(){返回视图(新的 CustomErrorViewModel(Response.Status));}}

自定义错误视图:

@{布局 = "~/Views/Shared/_CustomErrorLayout.cshtml";}@using System.Web.Configuration;@使用系统配置;@using MVC_Tests.Models;@model CustomErrorViewModel@section HttpCode { @Response.StatusCode }@Model.Status

布局是:

<头><meta name="viewport" content="width=device-width"/><title></title><link href="~/Content/CustomError.css" rel="stylesheet"/><身体><div id="divError"><h1><span>错误&nbsp;</span>@RenderSection("HttpCode")<div id="divErrorMessage"><p>@RenderBody()</p>

我尝试处理的错误是我添加到 Home Index 操作中的简单除以零.请注意,我想要一个单一视图来处理不同的服务器 http 状态错误代码(500 系列).我知道每个不同的 http 状态代码都有不同的视图,我希望通过一个视图来处理多个代码.

自定义错误处理正在工作,我在所需的视图中结束 - 但是 - 如上所述,我希望输出错误的 http 状态代码.相反,我总是显示 200 (OK),根据我的理解和调试,这是因为:

1.首先,在被零除时绊倒,引发异常.

2. 现在发生重定向,因为我的 web.config 指令以自定义方式处理错误(因为没有在 web.config 中指定特定的 http 状态代码,我处理每个 http同一控制器/视图中的状态错误代码(/Error").这里重要的是重定向是一个请求.

3. 步骤 2 中的重定向将我发送到错误控制器,然后将我发送到其呈现的视图.

4.在渲染视图时,http状态码插入到布局定义部分,添加了我的自定义消息,http状态码部分的输出如我所说:200(行).为什么,如果强制抛出 500 服务器端错误?因为,如果我没有错,视图会在不同的请求管道中呈现,即重定向管道,并且在重定向中 - 不会发生错误 - 并且我最终得到 200 (OK) 状态响应.

我浏览了 Dino Esposito 发表的关于处理 asp.net mvc 中的错误的帖子,但我不想向所有应用程序的控制器添加过滤器(OnException 和 HandleError 属性解决方案)(我可以创建一个具有此类过滤器的新基本控制器,并使所有其他人继承它,但这也需要更改所有控制器类).他提到的最后一种方法(处理 global.asax 的 Application_Error 事件)我不确定是否用于此目的 - 我必须在处理程序中发出重定向Response.Redirect"语句,这超出了能够设置自定义页面的灵活性在 web.config 中(我仍然可以重定向到 web.config 中定义的路由,但我想知道这对于看起来如此简单的东西是否会变得太麻烦).

将任何服务器错误的响应的 http 状态代码捕获到我的自定义错误视图中的最佳方法是什么?

解决方案

如果您使用的是 IIS7+,我会像这样禁用customerrors":

 

并像这样使用httpErrors:

<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace" defaultPath="/error"><remove statusCode="404"/><error statusCode="404" path="/error/notfound" responseMode="ExecuteURL"/></httpErrors>....

这允许您使用控制器中的以下内容获取显示 404 状态代码的非 url 更改错误页面:

公共类 ErrorController : 控制器{公共 ActionResult notfound(){Response.TrySkipIisCustomErrors = true;Response.StatusCode = (int)HttpStatusCode.NotFound;return View("OneErrorViewToRuleThemAll");}}

ps.errorMode"需要更改为Custom"才能在本地查看....取决于您的本地设置(即,如果您使用的是 IISExpress),您可能在上传到实时服务器之前看不到正确的错误.

pps.您可以使用单一视图OneErrorViewToRuleThemAll"来处理您决定以这种方式处理的任何状态代码的屏幕输出.每个 ErrorController Action 都会在这个视图上结束.

I am trying to implement a general custom error page in ASP.NET MVC 4. I basically set up an Error Layout, which defines a section for outputting the http status code of the response.

The view that I want my errors to end up at inherits such layout, and simply adds a message that comes from its model, which was instantiated and passed in the call to View() in the Controller (named "Error") I set up to handle custom errors, in the web.config.

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

The custom error controller:

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        return View(new CustomErrorViewModel(Response.Status));
    }
}

The custom error view:

@{
    Layout = "~/Views/Shared/_CustomErrorLayout.cshtml";
}

@using System.Web.Configuration;
@using System.Configuration;
@using MVC_Tests.Models;
@model CustomErrorViewModel

@section HttpCode { @Response.StatusCode }

@Model.Status

The layout is:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title></title>
    <link href="~/Content/CustomError.css" rel="stylesheet" />
</head>
<body>
    <div id="divError">
        <h1>
            <span>Error &nbsp;</span>
            @RenderSection("HttpCode")
        </h1>
        <div id="divErrorMessage">
            <p>@RenderBody()</p>
        </div>
    </div>
</body>
</html>

The error I am trying to handle is a simple division by zero I added to the Home Index action. Note that I want a single view to handle different server http status error codes (500 family). I know having a different view for each distinct http status code works, I am after a single view to handle multiple codes.

The custom error handling is working, I am ending in the desired view - but - as noted above, I expected to output the http status code of the error. Instead, I am always displaying 200 (OK), which, according to my understanding and debugging, happens because:

1. First, upon stumbling with the division by zero, an exception is raised.

2. Now a redirect takes place, due my web.config instructions to handle errors in a customized way (since no specific http status code was specified in the web.config, I handle every http status error code in the same controller/view ("/Error"). What is crucial here is that the redirect is a new request.

3. The redirect from step 2 sends me to the Error Controller, and it then sends me to its view, which is rendered.

4. In rendering the view, the http status code inserted into the layout defined section, my custom message is added, and the output of the http status code part is as I said: 200 (OK). Why, if a 500 server side error was forcibly thrown ? Because, if I am not wrong, the view is rendered within a different request pipe, the redirect one, and in redirecting - no errors occur - and I end up with a 200 (OK) status response.

I went over this post by Dino Esposito about handling errors in asp.net mvc, but I do not want to add filters (OnException and HandleError attribute solutions) to all the app's controllers (I could create a new base controller that has such filter, and make all the others inherit from it, but that also requires changing all controller classes). The last approach he mentions (handling global.asax's Application_Error event) I am not sure does serve this purpose - I have to issue a redirect "Response.Redirect" statement in the handler, which beats the flexibility of being able to set the custom pages in the web.config (I could still redirect to a route defined in the web.config, but I wonder if this is not getting too cumbersome for something that looks so simple).

What is the best way to catch the response's http status code of any server error into my custom error view ?

解决方案

If you're using IIS7+ I'd disable "customerrors" like so:

 <customErrors mode="Off" />

and use httpErrors like so:

<system.webServer>
 <httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace" defaultPath="/error">
     <remove statusCode="404" />
     <error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
 </httpErrors>
....

This allows you to get a non-url changing error page displaying with a 404 status code using the following in your controller:

public class ErrorController : Controller
{
public ActionResult notfound()
    {
        Response.TrySkipIisCustomErrors = true;
        Response.StatusCode = (int)HttpStatusCode.NotFound;
        return View("OneErrorViewToRuleThemAll");
    }
}

ps. "errorMode" needs to change to "Custom" to see it locally....depending on your local setup (i.e. if you're using IISExpress) you might not see the proper error until you upload to a live server.

pps. you could have the single view "OneErrorViewToRuleThemAll" to handle the on-screen output of whatever status codes you decide to handle this way. Each ErrorController Action would end up on this view.

这篇关于如何将服务器错误的 http 状态代码捕获到 ASP.NET MVC 中的通用自定义错误视图中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆