【问题标题】:Process html files with HttpModule to catch 404 errors on IIS7使用 HttpModule 处理 html 文件以捕获 IIS7 上的 404 错误
【发布时间】:2011-05-11 15:18:49
【问题描述】:

我的 HttpModule 处理异常时遇到了另一个问题。 (cfr. 我之前的帖子:Custom HttpModule for IIS 7 for integrated

一切正常,但仅适用于 aspx 页面。

我们想要使用这个 HttpModule 的主要原因是为了处理当有人试图访问一个不存在的 html 页面时发生的 404 异常。但我的 HttpModule 仅适用于 .aspx 页面,并且在 html 文件不存在时不会触发。

这是我在 web.conf 文件中设置的配置:

<system.webServer>
  <modules>
    <add name="AspExceptionHandler" 
         type="Company.Exceptions.AspExceptionHandler, Company.Exceptions" 
         preCondition="managedHandler" />
  </modules>
</system.webServer>

我也尝试将 'runAllManagedModulesForAllRequests="true"' 添加到模块节点,并将 'preCondition="managedHandler"' 添加到 "add" 节点,但这也没有用。

我已将运行 Web 应用程序的应用程序池设置为“集成”模式,因为我在 google 上发现了很多。

还有其他方法可以让我的 HttpModule 处理访问不存在的 html 页面时发生的异常吗?

谢谢!

【问题讨论】:

    标签: c# iis-7 httpmodule


    【解决方案1】:

    根据 Alexander 的回答做了一些研究,我也在我的 AspExceptionHandler 中实现了 IHttpHandler。

    我的班级现在看起来像:

    public class AspExceptionHandler : IHttpModule, IHttpHandler
        {
            public void Dispose() { }
    
            public void Init(HttpApplication context)
            {
                context.Error += new EventHandler(ErrorHandler);
            }
    
            private void ErrorHandler(object sender, EventArgs e)
            {
                HttpApplication application = (HttpApplication)sender;
                try
                {
                    // Gather information
                    Exception currentException = application.Server.GetLastError(); ;
                    String errorPage = "http://companywebsite.be/error.aspx";
    
                    HttpException httpException = currentException as HttpException;
                    if (httpException == null || httpException.GetHttpCode() != 404)
                    {
                        application.Server.Transfer(errorPage, true);
                    }
                    //The error is a 404
                    else
                    {
                        // Continue
                        application.Server.ClearError();
    
                        String shouldMail404 = true;
    
                        //Try and redirect to the proper page.
                        String requestedFile = application.Request.Url.AbsolutePath.Trim('/').Split('/').Last();
    
                        // Redirect if required
                        String redirectURL = getRedirectURL(requestedFile.Trim('/'));
                        if (!String.IsNullOrEmpty(redirectURL))
                        {
                            //Redirect to the proper URL
                        }
                        //If we can't redirect properly, we set the statusCode to 404.
                        else
                        {
                            //Report the 404
                        }
                    }
                }
                catch (Exception ex)
                {
                    ExceptionCatcher.FillWebException(HttpContext.Current, ref ex);
                    ExceptionCatcher.CatchException(ex);
                }
            }
    
            public bool IsReusable
            {
                get { return true; }
            }
    
            public void ProcessRequest(HttpContext context)
            {
                if (!File.Exists(context.Request.PhysicalPath)) 
                {
                    throw new HttpException(404, String.Format("The file {0} does not exist", context.Request.PhysicalPath));
                }
                        else
                {
                    context.Response.TransmitFile(context.Request.PhysicalPath);
                }
            }
        }
    

    在 ProcessRequest 方法(IHttpHandler 要求)中,我检查文件是否存在。 如果它不存在,我会抛出一个被我的类的 HttpModule 部分捕获的 HttpException。

    我的 web.config 中的 system.webServer 节点现在如下所示:

    <modules runAllManagedModulesForAllRequests="true">
                <add name="AspExceptionHandler" type="Company.Exceptions.AspExceptionHandler, Company.Exceptions" preCondition="managedHandler" />
            </modules>
            <handlers>
                <add name="AspExceptionHandler" type="Company.Exceptions.AspExceptionHandler, Company.Exceptions" verb="*" path="*.html" />
            </handlers>
    

    我在这篇文章中找到了答案:HttpHandler fire only if file doesn't exist

    【讨论】:

    • +1 用于在到期时给予信用。它大部分是正确的,但有点愚蠢。为什么要创建一个既是模块又是处理程序的类?您只是在真正使用处理程序方面。此外,如果你想将它注册为“*”(任何从裂缝中掉下来的东西),它就会越过它的界限并阻止其他处理程序工作。 :(
    • 感谢您的来信。
    【解决方案2】:

    你可以试试这个

    <httpHandlers>
        <add type="Company.Exceptions.AspExceptionHandler, Company.Exceptions" verb="*" path="*"/> 
        ....
    </httpHandlers>
    

    这可以帮助您捕获所有请求,但是如果对现有页面进行请求,则需要将其传递给标准处理程序

    【讨论】:

    • AspExceptionHandler 不是必须是 IHttpHandler 才能添加为处理程序吗?好吧,我已经测试过了,我得到了错误 AspExceptionHandler 没有实现 IHttpHandler,或者这就是你所说的,我应该将我的类转换为 HttpHandler 以便它处理所有请求?
    • 对不起,我以为你的课程是 IHttpHandler 因为它的名字:) 无论如何,我希望这个答案能告诉你这样做的方法
    • 哦,是的,我使用了 AspExceptionHandler 因为它处理异常:)。您的帖子真的很有帮助,您可以在下面的回答中看到:)...非常感谢您的帮助!
    猜你喜欢
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多