我基本上设置了一个错误布局,它定义了一个输出响应的http状态代码的部分.
我希望我的错误最终继承这样的布局的视图,并简单地添加一个来自其模型的消息,该消息被实例化并传递给Controller中的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>
我试图处理的错误是一个简单的除零,我添加到Home Index操作.请注意,我想要一个视图来处理不同的服务器http状态错误代码(500系列).我知道每个不同的http状态代码都有不同的视图,我在一个视图之后处理多个代码.
自定义错误处理正在运行,我在所需的视图中结束 – 但是 – 如上所述,我希望输出错误的http状态代码.
相反,我总是显示200(OK),根据我的理解和调试,这是因为:
1.首先,在将除法绊倒时,会产生异常.
2.现在进行重定向,由于我的web.config指令以自定义方式处理错误(因为在web.config中没有指定特定的http状态代码,我在同一控制器/视图中处理每个http状态错误代码( “/错误”).这里至关重要的是重定向是一个新请求.
3.来自步骤2的重定向将我发送到错误控制器,然后它将我发送到其视图,该视图将被渲染.
4.在渲染视图时,http状态代码插入布局定义部分,我的自定义消息被添加,http状态代码部分的输出如我所说:200(OK).为什么,如果强行抛出500服务器端错误?因为,如果我没有错,视图将在不同的请求管道中呈现,重定向,并且在重定向时 – 不会发生错误 – 我最终得到200(OK)状态响应.
我在Dino Esposito上发表了关于在asp.net mvc中处理错误的this帖子,但是我不想在所有应用程序的控制器中添加过滤器(OnException和HandleError属性解决方案)(我可以创建一个具有这种过滤器的新基本控制器,并使所有其他人继承它,但这也需要更改所有控制器类).他提到的最后一种方法(处理global.asax的Application_Error事件)我不确定是否可以实现此目的 – 我必须在处理程序中发出重定向“Response.Redirect”语句,这超出了能够设置自定义页面的灵活性在web.config中(我仍然可以重定向到web.config中定义的路由,但我想知道这对于看起来如此简单的事情来说是不是太麻烦了).
解决方法
<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 Action都会以此视图结束.