如何将服务器错误的 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
我正在尝试在 ASP.NET MVC 4 中实现一个通用的自定义错误页面。
我基本上设置了一个错误布局,它定义了一个用于输出响应的 http 状态代码的部分。
我希望我的错误结束的视图继承了这样的布局,并简单地添加了一条来自其模型的消息,该消息已实例化并在调用控制器中的 View() 时传递(名为 "Error") 我设置处理自定义错误,在web.config.
<customErrors defaultRedirect="/Error" mode="On">
</customErrors>
自定义错误控制器:
public class ErrorController : Controller
{
public ActionResult Index()
{
return View(new CustomErrorViewModel(Response.Status));
}
}
自定义错误视图:
@{
Layout = "~/Views/Shared/_CustomErrorLayout.cshtml";
}
@using System.Web.Configuration;
@using System.Configuration;
@using MVC_Tests.Models;
@model CustomErrorViewModel
@section HttpCode { @Response.StatusCode }
@Model.Status
布局为:
<!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 </span>
@RenderSection("HttpCode")
</h1>
<div id="divErrorMessage">
<p>@RenderBody()</p>
</div>
</div>
</body>
</html>
我试图处理的错误是我添加到主页索引操作中的一个简单的除以零。请注意,我想要一个 单一视图 来处理不同的服务器 http 状态错误代码(500 系列)。 我知道对每个不同的 http 状态代码使用不同的视图是可行的,我希望通过一个视图来处理多个代码。
自定义错误处理正在运行,我在所需的视图中结束 - 但是 - 如上所述,我希望输出错误的 http 状态代码。
相反,我总是显示 200 (OK),根据我的理解和调试,这是因为:
1.首先,在被零除时出错,引发异常。
2. 由于我的 web.config 指令以自定义方式处理错误(因为在 web.config,我在同一个 controller/view ("/Error") 中处理每个 http 状态错误代码。这里的关键是重定向是一个 new 请求。
3. 第 2 步的重定向将我发送到错误控制器,然后将我发送到它的视图,该视图已呈现。
4.渲染视图时,在布局定义部分插入http状态码,添加我的自定义消息,http状态码部分输出如下我说:200(好)。为什么,如果强制抛出 500 服务器端错误?因为,如果我没记错的话,视图是在不同的请求管道(重定向管道)中呈现的,并且在重定向中 - 没有发生错误 - 我最终得到 200(OK)状态响应。
我仔细阅读了 Dino Esposito this post 关于 asp.net mvc 中错误处理的内容,但我不想向所有应用程序的控制器(我可以创建一个具有此类过滤器的新基本控制器,并让所有其他控制器继承它,但这也需要更改所有控制器 类)。他提到的最后一种方法(处理 global.asax 的 Application_Error 事件)我不确定是否能达到这个目的——我必须在处理程序中发出重定向 "Response.Redirect" 语句,这比灵活性要差能够在 web.config 中设置自定义页面(我仍然可以重定向到 web.config 中定义的路由,但我想知道这对于看起来如此简单的东西来说是不是太麻烦了)。
将任何服务器错误的响应的 http 状态代码捕获到我的自定义错误视图中的最佳方法是什么?
如果您使用的是 IIS7+,我会像这样禁用 "customerrors":
<customErrors mode="Off" />
并像这样使用 httpErrors:
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace" defaultPath="/error">
<remove statusCode="404" />
<error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
</httpErrors>
....
这允许您在您的控制器中使用以下内容来获得显示 404 状态代码的非 url 更改错误页面:
public class ErrorController : Controller
{
public ActionResult notfound()
{
Response.TrySkipIisCustomErrors = true;
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View("OneErrorViewToRuleThemAll");
}
}
ps。 "errorMode" 需要更改为 "Custom" 才能在本地查看....取决于您的本地设置(即,如果您使用的是 IISExpress),在上传到实时服务器之前,您可能看不到正确的错误.
pps。您可以使用单一视图 "OneErrorViewToRuleThemAll" 来处理您决定以这种方式处理的任何状态代码的屏幕输出。每个 ErrorController 操作都会在此视图上结束。
描述了我正在寻找的解决方案(在处于放弃的边缘之后)here。
步骤总结:
- 将您的 web.config 设置为针对您要处理的每个错误重定向到控制器操作。
- 将Response对象的TryToSkipCustomErrors属性设置为true,在1.
中定义的每个动作中
- 注释掉该行
filters.Add(new HandleErrorAttribute());
来自您的 filterConfig.cs 文件。
使用这种方法,我终于成功地重定向到错误 500 的自定义页面。 IIS 似乎对 500 有某种默认跳过,因为设置了错误 404 的自定义页面不需要步骤 2 和 3。
所以,最后,对于我想要呈现自定义页面的每个 http 状态代码,我创建了一个控制器操作,相应地设置了描述的属性,然后针对所有操作重定向到相同的视图 - 我在这里显示@Response.Status,使其成为我的通用解决方案。
我正在尝试在 ASP.NET MVC 4 中实现一个通用的自定义错误页面。 我基本上设置了一个错误布局,它定义了一个用于输出响应的 http 状态代码的部分。
我希望我的错误结束的视图继承了这样的布局,并简单地添加了一条来自其模型的消息,该消息已实例化并在调用控制器中的 View() 时传递(名为 "Error") 我设置处理自定义错误,在web.config.
<customErrors defaultRedirect="/Error" mode="On">
</customErrors>
自定义错误控制器:
public class ErrorController : Controller
{
public ActionResult Index()
{
return View(new CustomErrorViewModel(Response.Status));
}
}
自定义错误视图:
@{
Layout = "~/Views/Shared/_CustomErrorLayout.cshtml";
}
@using System.Web.Configuration;
@using System.Configuration;
@using MVC_Tests.Models;
@model CustomErrorViewModel
@section HttpCode { @Response.StatusCode }
@Model.Status
布局为:
<!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 </span>
@RenderSection("HttpCode")
</h1>
<div id="divErrorMessage">
<p>@RenderBody()</p>
</div>
</div>
</body>
</html>
我试图处理的错误是我添加到主页索引操作中的一个简单的除以零。请注意,我想要一个 单一视图 来处理不同的服务器 http 状态错误代码(500 系列)。 我知道对每个不同的 http 状态代码使用不同的视图是可行的,我希望通过一个视图来处理多个代码。
自定义错误处理正在运行,我在所需的视图中结束 - 但是 - 如上所述,我希望输出错误的 http 状态代码。 相反,我总是显示 200 (OK),根据我的理解和调试,这是因为:
1.首先,在被零除时出错,引发异常。
2. 由于我的 web.config 指令以自定义方式处理错误(因为在 web.config,我在同一个 controller/view ("/Error") 中处理每个 http 状态错误代码。这里的关键是重定向是一个 new 请求。
3. 第 2 步的重定向将我发送到错误控制器,然后将我发送到它的视图,该视图已呈现。
4.渲染视图时,在布局定义部分插入http状态码,添加我的自定义消息,http状态码部分输出如下我说:200(好)。为什么,如果强制抛出 500 服务器端错误?因为,如果我没记错的话,视图是在不同的请求管道(重定向管道)中呈现的,并且在重定向中 - 没有发生错误 - 我最终得到 200(OK)状态响应。
我仔细阅读了 Dino Esposito this post 关于 asp.net mvc 中错误处理的内容,但我不想向所有应用程序的控制器(我可以创建一个具有此类过滤器的新基本控制器,并让所有其他控制器继承它,但这也需要更改所有控制器 类)。他提到的最后一种方法(处理 global.asax 的 Application_Error 事件)我不确定是否能达到这个目的——我必须在处理程序中发出重定向 "Response.Redirect" 语句,这比灵活性要差能够在 web.config 中设置自定义页面(我仍然可以重定向到 web.config 中定义的路由,但我想知道这对于看起来如此简单的东西来说是不是太麻烦了)。
将任何服务器错误的响应的 http 状态代码捕获到我的自定义错误视图中的最佳方法是什么?
如果您使用的是 IIS7+,我会像这样禁用 "customerrors":
<customErrors mode="Off" />
并像这样使用 httpErrors:
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace" defaultPath="/error">
<remove statusCode="404" />
<error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
</httpErrors>
....
这允许您在您的控制器中使用以下内容来获得显示 404 状态代码的非 url 更改错误页面:
public class ErrorController : Controller
{
public ActionResult notfound()
{
Response.TrySkipIisCustomErrors = true;
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View("OneErrorViewToRuleThemAll");
}
}
ps。 "errorMode" 需要更改为 "Custom" 才能在本地查看....取决于您的本地设置(即,如果您使用的是 IISExpress),在上传到实时服务器之前,您可能看不到正确的错误.
pps。您可以使用单一视图 "OneErrorViewToRuleThemAll" 来处理您决定以这种方式处理的任何状态代码的屏幕输出。每个 ErrorController 操作都会在此视图上结束。
描述了我正在寻找的解决方案(在处于放弃的边缘之后)here。
步骤总结:
- 将您的 web.config 设置为针对您要处理的每个错误重定向到控制器操作。
- 将Response对象的TryToSkipCustomErrors属性设置为true,在1. 中定义的每个动作中
- 注释掉该行
filters.Add(new HandleErrorAttribute());
来自您的 filterConfig.cs 文件。
使用这种方法,我终于成功地重定向到错误 500 的自定义页面。 IIS 似乎对 500 有某种默认跳过,因为设置了错误 404 的自定义页面不需要步骤 2 和 3。
所以,最后,对于我想要呈现自定义页面的每个 http 状态代码,我创建了一个控制器操作,相应地设置了描述的属性,然后针对所有操作重定向到相同的视图 - 我在这里显示@Response.Status,使其成为我的通用解决方案。