简体   繁体   English

web.config / Global.asax中的自定义错误处理不处理不存在的目录

[英]Custom Error Handling in web.config / Global.asax not handling non-existant directory

Question is: Why is custom Error handling not working for non-existing paths/directories? 问题是:为什么自定义错误处理不适用于不存在的路径/目录?

Updated with fixed code (thanks to everyone for you input): 更新了固定代码(感谢大家为您输入):

* Updated code for web.config and global.asax * *更新了web.config和global.asax *的代码

<httpErrors errorMode="Custom">
        <remove statusCode="500" subStatusCode="-1" />
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" subStatusCode="-1" prefixLanguageFilePath="" path="/*****.aspx" responseMode="ExecuteURL" />
        <error statusCode="500" subStatusCode="-1"  prefixLanguageFilePath="" path="/*****.aspx"  responseMode="ExecuteURL"/>
    </httpErrors>

    added this to the global.asax to stop IIS from handling my 500 errors
    after @Kev's suggestions IIS handled my 500's these lines fixed that
    HttpApplication myApplication = new HttpApplication();
    myApplication.Response.TrySkipIisCustomErrors = true;

We have a site setup with custom error handling in web.config and global.asax (the setup is shown below). 我们在web.configglobal.asax有一个自定义错误处理的站点设置(设置如下所示)。 We are able to handle all 404's and 500's with no problems. 我们能够毫无问题地处理所有404和500。 The errors are caught in the Application_Error in the global.asax , logged to a DB then using HttpContext we set the status code and use Server.Transfer() to move the user to the appropriate error page (redirects cause a 302, and hurts SEO). 错误被捕获到global.asax中的Application_Error ,记录到DB然后使用HttpContext我们设置状态代码并使用Server.Transfer()将用户移动到相应的错误页面(重定向导致302,并且伤害SEO )。

The problem is when the user types in http://www.example.com/whatever a blank page is shown in Firefox and in IE it shows the IE 404 page. 问题是当用户输入http://www.example.com/whatever Firefox中显示空白页时,IE显示IE 404页面。 Firebug shows no status codes being fired, and when I debug the solution, no breakpoints I have set are hit in the global.asax . Firebug显示没有触发状态代码,当我调试解决方案时,我设置的断点没有在global.asax中命中。 The odd thing is that a user can enter http://www.example.com/whatever/hmm.aspx and an error will be hit. 奇怪的是用户可以输入http://www.example.com/whatever/hmm.aspx并且会出现错误。 It seems it's only working on non-existing pages and not paths/directories that don't exist. 它似乎只适用于不存在的页面而不是不存在的路径/目录。

Below is my web.config code for the Errors and my global.asax code for Application error. 下面是我的错误的web.config代码和Application错误的global.asax代码。

I've added the * * to hide info, they have valid .aspx pages in them: 我添加了* *来隐藏信息,它们中包含有效的.aspx页面:

Web config: 网络配置:

<customErrors defaultRedirect="~/******.aspx" mode="On" 
              redirectMode="ResponseRewrite">
    <error statusCode="500" redirect="~/*****.aspx" />
    <error statusCode="404" redirect="~/*****.aspx" />
</customErrors>

    <httpErrors errorMode="Custom">
        <remove statusCode="500" subStatusCode="-1" />
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" subStatusCode="-1" prefixLanguageFilePath="" path="/*****.aspx" responseMode="ExecuteURL" />
        <error statusCode="500" subStatusCode="-1"  prefixLanguageFilePath="" path="/*****.aspx"  responseMode="ExecuteURL"/>
    </httpErrors>

Code: 码:

protected void Application_Error(Object sender, EventArgs e)
{
    // At this point we have information about the error
    HttpContext ctx = HttpContext.Current;

    // set the exception to the Context 
    Exception exception = ctx.Server.GetLastError();

    // get the status code of the Error
    int httpCode = ((HttpException)exception).GetHttpCode();

    // get the IP Address
    String strHostName = string.Empty;
    String ipAddress_s = string.Empty;
    strHostName = System.Net.Dns.GetHostName();

    System.Net.IPHostEntry ipEntry = System.Net.Dns.GetHostByName(strHostName);
    System.Net.IPAddress[] addr = ipEntry.AddressList;

    for (int i = 0; i < addr.Length; i++)
    {
        ipAddress_s += "IP Address {" + (i + 1) + "} " + 
                            addr[i].ToString() + Environment.NewLine;
    }

    // setup the error info one for user display and one for the DB Insert
    string errorInfo =
       "<br /><b>Error Location:</b> " + ctx.Request.Url.ToString() +
       "<br /><br /><b>Error Source:</b> " + exception.Source +
       "<br /><br /><b>Error Try/Catch:</b> " + exception.InnerException +
       "<br /><br /><b>Error Info:</b> " + exception.Message +
       "<br /><br /><b>Status Code:</b> " + httpCode +
       "<br /><br /><b>Stack trace:</b> " + exception.StackTrace;
    string errorInfoDB =
       "||Error Location: " + ctx.Request.Url.ToString() +
       "||Error Source: " + exception.Source +
       "||Error Try/Catch: " + exception.InnerException +
       "||Error Info: " + exception.Message +
       "||HttpErrorCode: " + httpCode +
       "||Stack trace: " + exception.StackTrace +
       "||IP Address: " + ipAddress_s;

    // clean the input befor you put it in the DB
    char quote = (char)34;
    char filler = (char)124;
    char tick = (char)39;
    char greaterThan = (char)60;
    char lessThan = (char)62;
    errorInfo = errorInfo.Replace(quote, filler);
    errorInfo = errorInfo.Replace(tick, filler);
    errorInfo = errorInfo.Replace(greaterThan, filler);
    errorInfo = errorInfo.Replace(lessThan, filler);

    errorInfoDB = errorInfoDB.Replace(quote, filler);
    errorInfoDB = errorInfoDB.Replace(tick, filler);
    errorInfoDB = errorInfoDB.Replace(greaterThan, filler);
    errorInfoDB = errorInfoDB.Replace(lessThan, filler);

    string pattern = string.Empty;
    string replacement = "sQueEl";
    pattern = "/cookie|SELECT|UPDATE|INSERT|INTO|DELETE|FROM|NOT IN|WHERE|TABLE|DROP|script*/ig";
    errorInfoDB = Regex.Replace(errorInfoDB, pattern, replacement);

    pattern = "/cookie|select|update|insert|into|delete|from|not in|where|table|drop|script*/ig";
    errorInfoDB = Regex.Replace(errorInfoDB, pattern, replacement);


    if (httpCode == 404)
    {
        InSert_To_DB_Class(*****, *****, *****, *****, *****, errorInfoDB);
    }
    else
    {
        InSert_To_DB_Class(*****, *****, *****, *****, *****, errorInfoDB);
    }

    // set the error info to the session variable to display to the allowed users
    Application["AppError"] = errorInfo;

    // clear the error now that is has been stored to a session
    ctx.Server.ClearError();
    ctx.Response.ClearHeaders();
    // set the status code so we can return it for SEO
    ctx.Response.StatusCode = httpCode;
    ctx.Response.TrySkipIisCustomErrors = true;
    HttpApplication myApplication = new HttpApplication();
    myApplication.Response.TrySkipIisCustomErrors = true;
    try
    {
        if (ctx.Request.RawUrl.Contains("/*****"))
        {
            // redirect to the error page
            ctx.Server.Transfer("~/*****.aspx", false);
        }
        else if(ctx.Request.RawUrl.Contains("/*****"))
        {
            ctx.Server.Transfer("~/*****/*****.aspx", false);
        }
        else
        {
            // check the httpCode
            if (httpCode == 404)
            {
                // set the page name they were trying to find to a session variable
                // this will be cleared in the ****** page
                Application["404_page"] = exception.Message; 
                // redirect to the 404 page
                ctx.Server.Transfer("~/*****", false);
            }
            else
            {
                // redirect to the error page
                ctx.Server.Transfer("~/*****", false);
            }
        }
    }
}

From this comment to Mr. Disappointment: 从评论到失望先生:

Thanks, I'm using IIS 7 local and IIS 7.5 on live. 谢谢,我正在使用IIS 7本地和IIS 7.5。 Let me know when you find the material. 当你找到这些材料时,请告诉我。

If your application is running in an application pool configured to run in Classic Pipeline mode then content not intended for ASP.NET won't hit the ASP.NET runtime. 如果您的应用程序在配置为以经典管道模式运行的应用程序池中运行,则不适用于ASP.NET的内容将不会访问ASP.NET运行时。 ie folders that don't exist. 即不存在的文件夹。 These will be handled directly by IIS. 这些将由IIS直接处理。

You have a couple choices: 你有几个选择:

  1. Set the application pool to Integrated Pipeline mode. 将应用程序池设置为Integrated Pipeline模式。 You may also need to configure the following setting if IIS's error handling "eats" your ASP.NET 404 and 500 status code from ASP.NET: 如果IIS的错误处理从ASP.NET“”占用“ASP.NET 404和500状态代码,则可能还需要配置以下设置:

     <configuration> <system.webServer> <httpErrors existingResponse="PassThrough" /> </system.webServer> </configuration> 
  2. If the application is not well behaved in "Integrated Pipeline" mode but you're just concerned about getting a page displayed for a 404 response then configure the following: 如果应用程序在“集成管道”模式下表现不佳,但您只关心为404响应显示页面,请配置以下内容:

     <system.webServer> <httpErrors> <remove statusCode="404" subStatusCode="-1" /> <error statusCode="404" prefixLanguageFilePath="" path="/404.aspx" responseMode="ExecuteURL" /> </httpErrors> </system.webServer> 

    You'd need to set the 404 status code in the page, otherwise it'll just return a 200 . 您需要在页面中设置404状态代码,否则它将返回200

    If you use a static page, for example: 如果您使用静态页面,例如:

     <error statusCode="404" prefixLanguageFilePath="" path="404.html" responseMode="File" /> 

    This will return a 404 . 这将返回404

  3. If the application is not well behaved in "Integrated Pipeline" mode AND you absolutely must pass 404 errors through your error handler then you may have to manually map wildcard content to the ASP.NET HttpHandler so that such requests do hit the pipeline. 如果应用程序在“集成管道”模式下表现不佳并且您必须通过错误处理程序传递404错误,那么您可能必须手动将通配符内容映射到ASP.NET HttpHandler,以便此类请求确实可以访问管道。 This would be a sub-optimal solution. 这将是次优解决方案。

ASP.NET is never being invoked by IIS. IIS永远不会调用ASP.NET。 IIS handles the page request, sees that the page doesn't exist, and ASP.NET never gets loaded. IIS处理页面请求,发现页面不存在,ASP.NET永远不会被加载。

If you want ASP.NET to get loaded regardless of whether the file exists, you need to change your IIS configuration. 如果您希望加载ASP.NET而不管文件是否存在,则需要更改IIS配置。 Are you using IIS6 or IIS7/7.5? 您使用的是IIS6还是IIS7 / 7.5?

You need to set up wildcard mapping so that all requests go through .Net 您需要设置通配符映射,以便所有请求都通过.Net

if your using IIS6 the following link should help you out: 如果您使用IIS6,以下链接应该可以帮助您:

http://professionalaspnet.com/archive/2007/07/27/Configure-IIS-for-Wildcard-Extensions-in-ASP.NET.aspx http://professionalaspnet.com/archive/2007/07/27/Configure-IIS-for-Wildcard-Extensions-in-ASP.NET.aspx

Wildcard script mapping and IIS 7 integrated pipeline: 通配符脚本映射和IIS 7集成管道:

http://learn.iis.net/page.aspx/508/wildcard-script-mapping-and-iis-7-integrated-pipeline/ http://learn.iis.net/page.aspx/508/wildcard-script-mapping-and-iis-7-integrated-pipeline/

I can't find the source material for this but I believe the problem lies in the fact it is handling custom error pages and not paths . 我找不到这个的源材料,但我相信问题在于它处理自定义错误页面不是 路径

You investigation suggests you came across this, inasmuch as: 你调查显示你遇到过这个,因为:

www.mysite.com/nonexistingpath/nonexistingpage.aspx

This ought to hit the correct error page. 这应该打到正确的错误页面。 The following won't: 以下不会:

www.mysite.com/nonexistingpath/

This kind of reiterates you already answering your own question, but I'll see if I can find the reference material. 这种情况重申你已经回答了自己的问题,但我会看看能不能找到参考资料。 Ultimately, it isn't a page request, so there is no ISAPI handling through appropriate handlers. 最终,它不是页面请求,因此没有通过适当的处理程序处理ISAPI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Global.asax中以编程方式加密Web.Config - Encrypt Web.Config Programmatically in Global.asax 在web.config或global.asax EndRequest事件中重定向401? - Redirect 401 in web.config or global.asax EndRequest event? 不存在的目录/文件Web API(非控制器)的自定义错误页面 - Custom error pages for non-existant directory/file Web API (not controllers) MVC .Net Web应用程序-组合web.config和global.asax-或不使用web.config进行部署 - MVC .Net web app - Combine web.config and global.asax - or deploy without web.config ASP.NET MVC自定义错误处理Application_Error Global.asax? - ASP.NET MVC Custom Error Handling Application_Error Global.asax? Azure上global.asax中的异常处理 - Exceptions handling in global.asax on Azure 由于我在 Web.config 和 Global.asax 中的设置,NotFound 方法被调用两次 - A NotFound method is invoked twice due to my settings in Web.config and Global.asax 通过global.asax从外部类获取web.config请求 - Getting the web.config request from external class via global.asax ASP.NET 会话状态在 Web.config 和 Global.asax 中不起作用 - ASP.NET Session State not working in Web.config as well as Global.asax Nlog - Web.config 规则 - 仅用于 Global.asax 文件的日志文件? - Nlog - Web.config rules - log file only for Global.asax file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM