Jonas Verdickt
Jonas Verdickt

Reputation: 319

Process html files with HttpModule to catch 404 errors on IIS7

I am having another problem with my HttpModule that handles exceptions. (cfr. my previous post: Custom HttpModule for IIS 7 for integrated)

All works well, but only for aspx pages.

The main reason we wanted to use this HttpModule is to handle 404 exceptions that occur when someone tries to go to a html page that doesn't exist. But my HttpModule only works for .aspx pages and it isn't triggered when a html file doesn't exist.

This is the configuration that I have set up in my web.conf file:

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

I have also tried adding 'runAllManagedModulesForAllRequests="true"' to the module node, and 'preCondition="managedHandler"' to the "add" node, but this also didn't work.

I have set the Application pool on which my web application is running to "Integrated" mode, because I found this a lot on google.

Is there another way to make my HttpModule handle exceptions that occur when visiting a non existing html page?

Thanks!

Upvotes: 4

Views: 4371

Answers (2)

Jonas Verdickt
Jonas Verdickt

Reputation: 319

Having done a little research based on the answer of Alexander, I implemented IHttpHandler in my AspExceptionHandler as well.

My class now looks like:

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);
            }
        }
    }

In the ProcessRequest method (required by the IHttpHandler) I check if the file exists. If it does not exist, I throw an HttpException that is catched by the HttpModule part of my class.

The system.webServer node in my web.config now looks like this:

<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>

I found the answer in in this post: HttpHandler fire only if file doesn't exist

Upvotes: 3

Alexander
Alexander

Reputation: 1297

you can try this

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

this help you to catch all request, but if reqest is made for existing page you need to pass it to standart handler

Upvotes: 1

Related Questions