customErrors与自定义模块

时间:2016-10-20 10:13:40

标签: c# asp.net asp.net-mvc iis httpmodule

我目前正在设置httpErrors设置以处理500位: -

<httpErrors errorMode="Custom" existingResponse="Replace">
        ......
        <remove statusCode="500"/>
        <error statusCode="500" path="/server-error" responseMode="ExecuteURL"/>
</httpErrors>

这样可以正常工作,但是在iis收到错误的情况下,我仍然会看到死亡的黄色屏幕。一个例子是当实体框架无法连接到数据库并且我收到: -

  

无法打开数据库&#34; Test-DB&#34;登录请求。
登录失败。
用户登录失败&#39; sa&#39;。

我已设置customErrors来处理此问题: -

<customErrors mode="On" defaultRedirect="error.html" redirectMode="ResponseRedirect">
        <error statusCode="500" redirect="error.html" />
</customErrors>

只要modules没有preCondition="managedHandler",就会按预期工作。

我有一些处理图像和css文件的模块,它们位于同一个项目中。

<modules runAllManagedModulesForAllRequests="false">
        <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
        <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
        <add name="ImageHandler" type="foo.bar.ProductImageHandlerHttpModule" />
        <add name="CustomCssHandler" type="foo.bar.CustomCssHttpModule" />
        <add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
</modules>

评论这些,我得到error.html,让他们进去,我得到

  

运行时错误
描述:处理您的异常时发生异常   请求。此外,执行时发生了另一个异常   第一个例外的自定义错误页面。请求已经   终止。

在尝试显示error.html时显示项目中的模块也出错。

有没有人知道修复/解决方法?

3 个答案:

答案 0 :(得分:1)

这是一个艰难的情况 - 您的错误来自HttpModule,它针对每个请求运行 - 包括对error.html页面的请求。一种方法是仅通过您的服务器路由静态文件(例如error.html) - 并在.NET级别忽略它们;这可能并不总是可行的(有时在.NET级别处理静态文件很方便)。我能想到的唯一另一种方法是将global.asax挂钩到错误事件并自行处理(这将忽略customErrors

类似的东西:

public class Global : System.Web.HttpApplication
{
    protected void Application_Error(object sender, EventArgs e)
    {
        // is there an error ?
        var error = Server.GetLastError();
        if (error != null)
        {
            // mark the error as - "i'll handle it myself"
            Server.ClearError();
            // load error.html manually & dump it to response
            var content = File.ReadAllText(Server.MapPath("~/error.html"));
            Context.Response.Write(content);
            // set correct error code
            Context.Response.StatusCode = 500;
        }
    }
}

注意:这可以解决,但你看到了一般原则......

答案 1 :(得分:0)

正如@Ondrej所说,处理自定义错误页面时出现的另一个错误来自HttpModule上的未处理异常,因此有必要跳过或绕过customErrors文件web.config部分

此代码还包括如何跳过从IIS生成的自定义错误,除了生成自定义HTML错误页面:

protected void Application_Error(Object sender, EventArgs e)
{
    // Get last error occurred
    var exception = Server.GetLastError();

    // catch unhandled exceptions
    if (exception is HttpUnhandledException)
    {
        // handle the error by ASP .NET itself
        Server.ClearError();

        // write status code handling
        HttpContext.Current.Response.WriteFile(Server.MapPath("~/error.html"));
        HttpContext.Current.Response.StatusCode = 500;
        HttpContext.Current.Response.StatusDescription = "Internal Server Error";

        // set ASP .NET handlers instead of using IIS handlers
        HttpContext.Current.Response.TrySkipIisCustomErrors = true;
    }
}

此外,要删除IIS生成的YSOD页面,您可以设置existingResponse属性以将错误处理传递到ASP .NET Application_Error方法中,如下所示:

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="PassThrough">
    <remove statusCode="500" />
    <error statusCode="500" responseMode="File" path="/error.html" />
    </httpErrors>
</system.webServer>

根据Kanwaljeet Singla的解释(source here)设置背后的原因:

  

<强> existingResponse

     

此部分级别属性的值告诉自定义错误模块要做什么   当响应文本不为空时。如果模块调用   IHttpResponse :: SetStatus设置错误代码并设置   响应文本,existingResponse属性告诉自定义错误模块   应该用自己的错误文本或应该替换当前的响应文本   它让当前的响应文本通过。 Asp.Net和WCF是   设置错误响应文本的模块示例。这个属性可以   设置为以下三个值。

     
      
  • 替换 - 此值使自定义错误模块始终将错误信息替换为自定义错误模块生成的文本。如果   existingResponse设置为“Replace”,生成错误/异常   Asp.Net/WCF被IIS7错误取代。

  •   
  • PassThrough - 如果existingResponse被视为“PassThrough”,则自定义错误模块将始终通过模块的响应。   此设置将使自定义错误模块返回空白响应   模块不设置任何文本。

  •   
  • 自动 - 这是默认值,告诉自定义错误模块执行正确的事情。客户端看到的实际错误文本将是   受影响取决于返回的fTrySkipCustomErrors的值   IHttpResponse :: GetStatus调用。当TrySkipCustomErrors设置为   是的,自定义错误模块将让响应通过,但如果它   设置为false,自定义错误模块用自己的文本替换文本。   Asp.Net/WCF使用TrySkipCustomErrors调用IHttpResponse :: SetStatus   为true,以便IIS不会使用自己的错误覆盖它们的错误。什么时候   有效的errorMode是“详细的”,响应是非空的,这个   不管是什么,existingResponse的值都将作为“PassThrough”   TrySkipCustomErrors的值。

  •   

希望在为未处理的异常响应设置自定义错误页面时,这可能会找出基本的东西。

MSDN参考:

https://msdn.microsoft.com/en-us/library/ms690576(v=vs.90).aspx

https://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors(v=vs.110).aspx

SO参考文献:

IIS7 Overrides customErrors when setting Response.StatusCode?

How to send status code "500" for generic error page in IIS?

Getting IIS7 'one liner' error when using custom error settings in web.config

答案 2 :(得分:0)

如果你的iis设置为集成模式,那么模块仍将运行静态文件。如果将其设置为经典模式,它将忽略静态文件的托管模块。

请参阅此主题以获取更多信息,请参阅JoãoAngeloRequests for static files are hitting the managed code in ASP.NET MVC3

的答案

修复是您更改了处理程序以不抛出异常或将iis更改为经典模式,因此如果任何处理程序或其他部分抛出异常并且iis重定向到error.html,那么管理模块都不会命中。

相关问题