Since ASP.NET does not implement the customError pages properly for 404 errors, I want to implement a custom error handling module to take its place. There are numerous examples on the Internet what needs to be in the code, but very little on how to implement
it.
After implementing the following code, when I navigate to a page that does not exist, I get a standard 404 error from IIS. I do not think my handler is working or I should see my custom 404 error page.
I am using Visual Studio Team System 2008 within Windows Vista SP1. The target is .NET 3.5, and I am using IIS to debug my projects, running VS as administrator to accomplish this.
Public Class HttpErrorModule
Implements IHttpModule
Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
'Nothing to dispose.
End Sub
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler context.Error, New EventHandler(AddressOf Context_Error)
End Sub
Private Sub Context_Error(ByVal sender As Object, ByVal e As EventArgs)
Dim context As HttpContext = CType(sender, HttpApplication).Context
If (context.Error.GetType Is GetType(HttpException)) Then
' Get the Web application configuration.
Dim configuration As System.Configuration.Configuration = WebConfigurationManager.OpenWebConfiguration("~/web.config")
' Get the section.
Dim customErrorsSection As CustomErrorsSection = CType(configuration.GetSection("system.web/customErrors"), CustomErrorsSection)
' Get the collection
Dim customErrorsCollection As CustomErrorCollection = customErrorsSection.Errors
Dim statusCode As Integer = CType(context.Error, HttpException).GetHttpCode
'Clears existing response headers and sets the desired ones.
context.Response.ClearHeaders()
context.Response.StatusCode = statusCode
If (customErrorsCollection.Item(statusCode.ToString) IsNot Nothing) Then
context.Server.Transfer(customErrorsCollection.Get(statusCode.ToString).Redirect)
Else
context.Response.Flush()
End If
End If
End Sub
End Class
I think, you might have misinterpretted the httpContext.Response.StatusCode. As far as I'm aware in .NET there is in fact no way you can programatically catch the HttpStatusCode of your error unless you create a function that evaluates the Exception.Message
for certain words or by some other evaluating means. The Response.StatusCode is most likely returning '200' better known as 'Everything is fine continue what you're doing'. I noticed this today as I was Error debugging today using a similar http module and
was surprised to find 200 returned. This is probably the reason why when your doing the server transfer its not directing you to your chosen error page. Why does it return 200 and not 404? I'm not entirely sure myself but I'd create a breakpoint at that
bit of code and evaluate it for yourself.
I don't know about you but for me, Progamming just ain't Programming with out brackets and braces. (loosely translated as I dislike VB)
I set my breakpoint within the init sub, and it did not get hit when debugging so I have not had a chance to debug the other parts. Am I not loading it correctly from web.config?
As for its ability to programatically catch an error, it was posted on a SEO site by a well known author. He posted the source code and has also published a DLL (which I can't seem to get to work either). My assumption is that the code is correct as other
people have left feedback thanking him as it works in their project. So far no response from the question I left on his page.
I am trying to understand your question here. Does it mean you don't want user to see the asp.net generated code rather you want them to see a customErrorPage? If so, this is how I handled this problem:
I created ErrorPage.aspx and added the following line in the web.config file.
Unfortunately I'm not best suited to VB.NET I'm afraid, so I couldn't tell off hand whether the code was right or wrong. but I am interested if .NET is able to pick up on the status error code. Could you possibly post the URL of the article from which you
sourced the code for me and maybe I could try it out tomorrow for myself after I've interpreted it in to c#. The web.config code looks alright to me, you've not namespaced any of it, so by all rights if you've cut and paste it word for word it should work
but hey, these things happen. If I find anything more I'll let you know. Sorry I couldn't be much help.
I don't know about you but for me, Progamming just ain't Programming with out brackets and braces. (loosely translated as I dislike VB)
If a user browses to a page that does not exist, the correct error page loads.
The problem, and it is a big problem, is that when the non existent page is accessed, IIS and .NET send out a 302 status code, that the resource has moved, and then loads the custom 404 page with IIS and .NET sending out a 200 status code.
No where does it send out a 404 status code. Bad, Bad, Bad for SEO.
This can be verified by running Fiddler, or any other packet analytic software.
I have modified my 404PageNotFound.aspx to include:
Response.ClearHeaders()
Response.StatusCode = 404
But that does not do the trick either.
Bottom line is I want to get my iHTTPModule to work, and I can't seem to verify if it is even loading properly to intercept requests.
well, now I am convinced it is not even listening to requests.
I added the following line to init
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init Throw New HttpException("Exception Occured")
AddHandler context.Error, New EventHandler(AddressOf Context_Error)
End Sub
When I start the debugger, it just loads the home page of the project and does not throw the error leading me to believe it is not hooked incoming requests.
Thinking HttpErrorModule is a potential reserved word, I renamed my class and .vb file to myHttpErrorModule
kapcreations
Member
30 Points
26 Posts
Custom 404 Error via iHTTPHandlerModule and EventHandler
Jun 10, 2008 07:07 PM|LINK
Since ASP.NET does not implement the customError pages properly for 404 errors, I want to implement a custom error handling module to take its place. There are numerous examples on the Internet what needs to be in the code, but very little on how to implement it.
After implementing the following code, when I navigate to a page that does not exist, I get a standard 404 error from IIS. I do not think my handler is working or I should see my custom 404 error page.
I am using Visual Studio Team System 2008 within Windows Vista SP1. The target is .NET 3.5, and I am using IIS to debug my projects, running VS as administrator to accomplish this.
I have created an entry in my web.config file as
<system.web>
<httpModules>
<add name="HttpErrorModule" type="HttpErrorModule, HttpErrorModule" />
</httpModules>
</system.web>
I have tried turning errors Off, On, RemoteOnly and commenting out the entire section
<customErrors mode="Off" defaultRedirect="~/Error.aspx">
<error statusCode="403" redirect="~/403Forbidden.aspx" />
<error statusCode="404" redirect="~/404PageNotFound.aspx" />
</customErrors>
I have created HttpErrorModule.vb in the App_Code directory (code listed below)
Imports System.Web
Imports System.Web.Configuration
Public Class HttpErrorModule
Implements IHttpModule
Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
'Nothing to dispose.
End Sub
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler context.Error, New EventHandler(AddressOf Context_Error)
End Sub
Private Sub Context_Error(ByVal sender As Object, ByVal e As EventArgs)
Dim context As HttpContext = CType(sender, HttpApplication).Context
If (context.Error.GetType Is GetType(HttpException)) Then
' Get the Web application configuration.
Dim configuration As System.Configuration.Configuration = WebConfigurationManager.OpenWebConfiguration("~/web.config")
' Get the section.
Dim customErrorsSection As CustomErrorsSection = CType(configuration.GetSection("system.web/customErrors"), CustomErrorsSection)
' Get the collection
Dim customErrorsCollection As CustomErrorCollection = customErrorsSection.Errors
Dim statusCode As Integer = CType(context.Error, HttpException).GetHttpCode
'Clears existing response headers and sets the desired ones.
context.Response.ClearHeaders()
context.Response.StatusCode = statusCode
If (customErrorsCollection.Item(statusCode.ToString) IsNot Nothing) Then
context.Server.Transfer(customErrorsCollection.Get(statusCode.ToString).Redirect)
Else
context.Response.Flush()
End If
End If
End Sub
End Class
What am I missing?
404 error handler module httpmodule
LukeJones
Member
53 Points
18 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 07:53 PM|LINK
kapcreations,
I think, you might have misinterpretted the httpContext.Response.StatusCode. As far as I'm aware in .NET there is in fact no way you can programatically catch the HttpStatusCode of your error unless you create a function that evaluates the Exception.Message for certain words or by some other evaluating means. The Response.StatusCode is most likely returning '200' better known as 'Everything is fine continue what you're doing'. I noticed this today as I was Error debugging today using a similar http module and was surprised to find 200 returned. This is probably the reason why when your doing the server transfer its not directing you to your chosen error page. Why does it return 200 and not 404? I'm not entirely sure myself but I'd create a breakpoint at that bit of code and evaluate it for yourself.
kapcreations
Member
30 Points
26 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 08:04 PM|LINK
Thanks for the reply.
I set my breakpoint within the init sub, and it did not get hit when debugging so I have not had a chance to debug the other parts. Am I not loading it correctly from web.config?
As for its ability to programatically catch an error, it was posted on a SEO site by a well known author. He posted the source code and has also published a DLL (which I can't seem to get to work either). My assumption is that the code is correct as other people have left feedback thanking him as it works in their project. So far no response from the question I left on his page.
kapcreations
Member
30 Points
26 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 08:23 PM|LINK
how should I go about seeing if it is loaded properly?
mominlhp
Member
378 Points
131 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 08:23 PM|LINK
I created ErrorPage.aspx and added the following line in the web.config file.
web.config file:
<customErrors defaultRedirect="~/ErrorPage.aspx" mode="RemoteOnly" />
Please remember to click "Mark as Answer" if you get the answer.
Thanks
~AK
LukeJones
Member
53 Points
18 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 08:26 PM|LINK
Unfortunately I'm not best suited to VB.NET I'm afraid, so I couldn't tell off hand whether the code was right or wrong. but I am interested if .NET is able to pick up on the status error code. Could you possibly post the URL of the article from which you sourced the code for me and maybe I could try it out tomorrow for myself after I've interpreted it in to c#. The web.config code looks alright to me, you've not namespaced any of it, so by all rights if you've cut and paste it word for word it should work but hey, these things happen. If I find anything more I'll let you know. Sorry I couldn't be much help.
kapcreations
Member
30 Points
26 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 08:37 PM|LINK
let's say you have a web.config that looks like this:
<customErrors mode="On" defaultRedirect="~/Error.aspx">
<error statusCode="403" redirect="~/403Forbidden.aspx" />
<error statusCode="404" redirect="~/404PageNotFound.aspx" />
</customErrors>
If a user browses to a page that does not exist, the correct error page loads.
The problem, and it is a big problem, is that when the non existent page is accessed, IIS and .NET send out a 302 status code, that the resource has moved, and then loads the custom 404 page with IIS and .NET sending out a 200 status code. No where does it send out a 404 status code. Bad, Bad, Bad for SEO.
This can be verified by running Fiddler, or any other packet analytic software.
I have modified my 404PageNotFound.aspx to include:
Response.ClearHeaders()
Response.StatusCode = 404
But that does not do the trick either.
Bottom line is I want to get my iHTTPModule to work, and I can't seem to verify if it is even loading properly to intercept requests.
kapcreations
Member
30 Points
26 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 08:39 PM|LINK
The page can be found at this url
kapcreations
Member
30 Points
26 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 10, 2008 09:15 PM|LINK
using System.Web;
using System.Web.Configuration;
using System;
public class HttpErrorModule : IHttpModule
{
private void Context_Error(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
if((object.ReferenceEquals(context.Error.GetType(),typeof(HttpException))))
{
// Get the Web application configuration.
System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~/web.config");
// Get the section.
CustomErrorsSection customErrorsSection = (CustomErrorsSection)configuration.GetSection("system.web/customErrors");
// Get the collection
CustomErrorCollection customErrorsCollection = customErrorsSection.Errors;
int statusCode = ((HttpException)context.Error).GetHttpCode();
//Clears existing response headers and sets the desired ones.
context.Response.ClearHeaders();
context.Response.StatusCode = statusCode;
if ((customErrorsCollection.Get(statusCode.ToString()) != null))
{
context.Server.Transfer(customErrorsCollection.Get(statusCode.ToString()).Redirect);
}
else
{
context.Response.Flush();
}
}
}
#region IHttpModule Members
public void Dispose()
{
//Do nothing here
}
public void Init(HttpApplication context)
{
context.Error += new EventHandler(Context_Error);
}
#endregion
}
kapcreations
Member
30 Points
26 Posts
Re: Custom 404 Error via iHTTPHandler
Jun 11, 2008 12:18 AM|LINK
well, now I am convinced it is not even listening to requests.
I added the following line to init
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
Throw New HttpException("Exception Occured")
AddHandler context.Error, New EventHandler(AddressOf Context_Error)
End Sub
When I start the debugger, it just loads the home page of the project and does not throw the error leading me to believe it is not hooked incoming requests.
Thinking HttpErrorModule is a potential reserved word, I renamed my class and .vb file to myHttpErrorModule
My web.config now includes this entry:
<system.web>
<httpModules>
<add name="myHttpErrorModule" type="myHttpErrorModule" />
</httpModules>
</system.web>
Did something change in IIS 7 or VS 2008 that changes the way iHTTPModules are implemented in a .NET web application?