I have an ASP.NET page to handle "404 page not found" it's setup by configuring the <customErrors>
section in my web.config file and setting the custom error page for 404 errors in IIS manager.
It works as expected for pages in the root of my website but doesn't work in a subdirectory of the site - the hyperlinks and content in my custom error page have the wrong url base.
All the links in my error page are server-side controls (runat="server") and have their links based with "~/".
When I browse the site with http://mysite/nosuchfolder/nosuchfile
the page renders with links thinking it's being served from the root, rather from nosuchfolder
and as such all the links are broken in the browser as the browser is basing links from nosuchfolder
.
Is there any way to 'tell' the ASP.NET page to re-base links on a different folder/filename?
Notes:
/error404.aspx
<customErrors>
section to redirect to /error404.aspx
<base>
tag in the page, but I want to avoid thisScott Gu's article on URL rewriting put me on the right path (so to speak!) - thanks for the tip James.
The answer is to use Context.RewritePath(newPath)
Here is the code I use in my custom 404 page -
protected override void Render(HtmlTextWriter writer)
{
string rebase = Server.UrlDecode(Request.ServerVariables["QUERY_STRING"]);
if (rebase.Length>10 && rebase.StartsWith("404;"))
{
try
{
rebase = new Uri(rebase.Substring(4)).AbsolutePath;
}
catch
{
rebase = "/";
}
finally
{
Context.RewritePath(rebase);
}
}
base.Render(writer);
Response.StatusCode = 404;
}
To handle missing .aspx pages in the same way, there is a setting in web.config
called redirectMode
that you set to ResponseRewrite
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="~/error404.aspx" />
</customErrors>
This stops the default behaviour of redirecting the user to ~/error404.aspx?aspxerrorpath=badfile
Note: this setting is new to the latest ASP.NET service packs (e.g. Framework 3.5 SP1)