我无法设置IIS来为我的自定义错误页面提供MVC管道之外的错误。如果我在控制器中抛出一个异常,它就是所有文件,Application_Error事件处理:
protected void Application_Error(object sender, EventArgs e)
{
var error = Server.GetLastError();
var routeData = new RouteData();
routeData.Values["Controller"] = "Error";
routeData.Values["Area"] = "";
routeData.Values["Exception"] = error;
if (error is HttpException)
{
switch (((HttpException)error).GetHttpCode())
{
case 401:
routeData.Values["Action"] = "NotAllowed";
break;
case 403:
routeData.Values["Action"] = "NotAllowed";
break;
case 404:
routeData.Values["Action"] = "NotFound";
break;
default:
routeData.Values["Action"] = "ServerError";
break;
}
}
else
{
routeData.Values["Action"] = "ServerError";
}
Response.Clear();
Server.ClearError();
IController controller = new ErrorController();
controller.Execute(new RequestContext(new HttpContextWrapper(((MvcApplication)sender).Context), routeData));
}
但是,如果我浏览到一个不存在的URL,IIS将处理404错误(或任何其他错误),给我标准的IIS错误消息并完全忽略我的web.config设置:
<system.web>
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="/error">
<error statusCode="401" redirect="/error/notallowed" />
<error statusCode="403" redirect="/error/notallowed" />
<error statusCode="404" redirect="/error/notfound" />
<error statusCode="500" redirect="/error/servererror" />
</customErrors>
</system.web>
<system.webServer>
<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
<clear />
<error statusCode="401" path="/error/notallowed" />
<error statusCode="403" path="/error/notallowed" />
<error statusCode="404" path="/error/notfound" />
<error statusCode="500" path="/error/servererror" />
</httpErrors>
</system.webServer>
/ error / *由我的应用程序内的控制器处理。我该怎么做才能使IIS执行自定义错误路径,而不是向我提供标准错误页面?
这是在Azure上运行的ASP.NET MVC 3。它在直接IIS下也不起作用,但开发服务器确实执行控制器。
答案 0 :(得分:9)
IIS不尊重defaultResponseMode。您必须将responseMode添加到每个错误中,如下所示:
<httpErrors errorMode="Custom">
<clear />
<error statusCode="401" path="/error/notallowed" responseMode="ExecuteURL" />
<error statusCode="403" path="/error/notallowed" responseMode="ExecuteURL" />
<error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
<error statusCode="500" path="/error/servererror" responseMode="ExecuteURL" />
</httpErrors>
为什么默认不适用于我。
答案 1 :(得分:4)
我遇到了这个问题而且我在Azure上,以下为我解决了这个问题:
Response.TrySkipIisCustomErrors = true;
答案 2 :(得分:3)
我在网上找到了很多解决方案,但两者都没有用于静态文件(例如对于不存在的'picture.jpg')。
此解决方案适用于Azure WebSites和Azure WebRole实例。我使用web.config
转换,因此根据您自己的需要更新它。
我使用ASPX页面进行错误,因此我可以设置正确的HTTP响应代码(当我使用.htm页面时,IIS总是设置HTTP 200)
档案~/404.aspx
是:
<%@ Page Language="C#" AutoEventWireup="false" ContentType="text/html" Debug="false" EnableEventValidation="false" EnableSessionState="False" EnableViewState="false" ResponseEncoding="utf-8" Transaction="Disabled" ValidateRequest="false" ViewStateMode="Disabled" %>
<% Context.Response.StatusCode = 404; %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>404 Error - Page not found</title>
</head>
<body>
<h1>Custom 404 page</h1>
</body>
</html>
档案~/500.aspx
是:
<%@ Page Language="C#" AutoEventWireup="false" ContentType="text/html" Debug="false" EnableEventValidation="false" EnableSessionState="False" EnableViewState="false" ResponseEncoding="utf-8" Transaction="Disabled" ValidateRequest="false" ViewStateMode="Disabled" %>
<% Context.Response.StatusCode = 500; %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>500 Server Error</title>
</head>
<body>
<h1>Custom 500 page</h1>
</body>
</html>
来自~/Web.config
的必要部分包含:
<?xml version="1.0"?>
<configuration>
<system.web>
<customErrors mode="Off" />
</system.web>
<system.webServer>
<httpErrors errorMode="Detailed" />
</system.webServer>
</configuration>
来自~/Web.Release.config
的必要部分包含:
<?xml version="1.0"?>
<configuration>
<customErrors mode="On" defaultRedirect="/500.aspx" redirectMode="ResponseRewrite" xdt:Transform="Replace">
<!-- AWARE do NOT use address in form "~/404.htm" but in "/404.htm" -->
<error statusCode="404" redirect="/404.aspx" />
<error statusCode="500" redirect="/500.aspx"/>
</customErrors>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace" xdt:Transform="Replace">
<!-- AWARE do NOT use address in form "~/404.htm" but in "/404.htm" -->
<remove statusCode="404" />
<error statusCode="404" path="/404.aspx" responseMode="ExecuteURL" />
<remove statusCode="500" />
<error statusCode="500" path="/500.aspx" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
</configuration>
结束。
答案 3 :(得分:0)
确保您已设置此设置。
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
否则您的IIS应用程序也可能在经典模式下运行而不是集成模式,这是一个IIS设置,但我认为集成模式是Azure中的默认模式(但说实话我没有检查过)