IIS将自定义错误页面作为纯文本提供,没有内容类型标题

时间:2013-03-13 11:34:44

标签: c# iis asp.net-mvc-4 error-handling

UPD :这是full solution for error handling

我有一个简单的vanilla MVC4网络项目。没有添加,没有删除,只是在Visual Studio中创建了一个新项目。

web.config我添加了自定义错误页面处理程序:

<customErrors mode="On" defaultRedirect="~/Content/Error.htm" redirectMode="ResponseRewrite" />

~/Content/Error.htm文件是:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>OOPS! Error Occurred. Sorry about this.</title>
</head>
<body>
    <h2>OOPS! Error Occurred</h2>
</body>
</html>

每当我在网站上收到404错误时,Error.htm在Firefox和Chrome中作为纯文本提供:

HTML is displayed as plain text

Fiddler说错误页面没有content-type标题,导致浏览器将页面呈现为纯文本:

No Content-type header

有没有办法强制使用content-type标题的IIS服务器错误页面

P.S。实际问题出在一个复杂的MVC4项目中,它在Global.asax中有自己的错误处理。但我发现有些错误不会通过ASP管道,只能由IIS处理。像dot at the end of the url一样。使用< httpErrors />的解决方案确实提供了正确的响应,但我们在Global.asax,Application_Error()中的自定义错误处理不会以这种方式调用。

UPD 似乎我无法赢得这场战争。 IE显示正确呈现的html,Firefox和Chrome显示为纯文本。当我切换到纯文本时,Firefox和IE正确显示空白区域,IE吞下白色空间并尝试渲染html。如果我尝试将图像作为错误页面提供,则Firefox和Chrome会显示图像。 IE显示了这个: IE9 is on crack! 捂脸!

4 个答案:

答案 0 :(得分:15)

使用.aspx而不是.htm作为错误页面(将htm重命名为aspx)。

<customErrors mode="On" defaultRedirect="~/Content/Error.aspx" redirectMode="ResponseRewrite" />

答案 1 :(得分:6)

显然,<customErrors>让工作变得一团糟。如果您决定使用它,Ben Foster对此主题有一个很好的写作:http://benfoster.io/blog/aspnet-mvc-custom-error-pages

如果您想使用.cshtml页面,最好的办法是放弃<customErrors>并处理Global.asax.cs中的错误:

protected void Application_Error(object sender, EventArgs e)
{
    var exception = Server.GetLastError();
    if (exception != null)
    {
        Response.Clear();
        HttpException httpException = exception as HttpException;
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        if (httpException == null)
        {
            routeData.Values.Add("action", "Unknown");
        }
        else
        {
            switch (httpException.GetHttpCode())
            {
                case 404:               // Page not found.
                    routeData.Values.Add("action", "NotFound");
                    break;

                default:
                    routeData.Values.Add("action", "Unknown");
                    break;
            }
        }


        // Pass exception details to the target error View.
        routeData.Values.Add("Error", exception);
        // Clear the error on server.
        Server.ClearError();
        // Avoid IIS7 getting in the middle
        Response.TrySkipIisCustomErrors = true;
        // Ensure content-type header is present
        Response.Headers.Add("Content-Type", "text/html");
        // Call target Controller and pass the routeData.
        IController errorController = new ErrorController();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    }
}

当然,您还需要使用适当的方法和.cshtml视图添加ErrorController。

public class ErrorController : Controller
{
    public ActionResult Index()
    {// your implementation
    }

    public ActionResult Unknown(Exception error)
    {// your implementation 
    }

    public ActionResult NotFound(Exception error)
    {// your implementation         
    }
}

答案 2 :(得分:5)

这显然是一个已知的错误,微软的建议符合spiatrax将htm / html重命名为aspx的想法。在我的情况下,我还必须包括

<% Response.StatusCode = 400 %>
<。>在.aspx页面中。

有关详细信息:http://connect.microsoft.com/VisualStudio/feedback/details/507171/

答案 3 :(得分:1)

我在system.webServer/httpprotocol下的自定义标头上添加了内容类型标头,并对其进行了修复。

<customHeaders><remove name="Content-Type" /><add name="ContentType"value="text/html" /></customHeaders>