Serving IIS Default Document with Extensionless ASP.NET
One of the great things I enjoy about ASP.NET is how much easier it becomes to write the .NET equivalent of ISAPI filters, being HttpModules, HttpHandlers, and such. I first heard of extensionless ASP.NET when Brad wrote about it on his weblog. I was hooked, my whole application can be powered by a single assembly and no aspx files (forgetting for the moment that my assembly relies on the hundreds of assemblies found in the Framework). The problem that I faced when I got my hosting provider to map .* to aspnet_isapi.dll was that my default documents weren't being served. Going to http://kilic.net/ would return a 401.3 Access Denied message. I was at a loss as to why but then it clicked, everything goes through aspnet_isapi.dll. I'm not entirely sure on where default documents enter the pipeline but having extensionless ASP.NET and default documents seemed to me a no-go situation. All is not lost however, below is an HttpModule that to a lesser extent mimics the default document serving from IIS. Feel free to correct, critique, or thank me :)
public class DefaultDocumentRedirect : IHttpModule
{
public void Init (HttpApplication httpApp)
{
httpApp.BeginRequest += new EventHandler(OnBeginRequest);
httpApp.EndRequest += new EventHandler (OnEndRequest);
}
void OnBeginRequest (object sender, EventArgs e)
{
HttpApplication httpApp = sender as HttpApplication;
// We first check that we're dealing with a directory by calling
// Directory.Exists. If the request was for a file then
// Directory.Exists would be false, so we let
// ASP.NET handle the request.
// However, if it is true we append the trailing slash (if
// missing) and append the file name, in this case default.aspx
// Note that this doesn't handle multiple default documents and that
// you can only do a Server.Transfer to an aspx page.
string physicalPath = httpApp.Context.Server.MapPath(httpApp.Context.Request.RawUrl);
try {
if (Directory.Exists(physicalPath))
{
httpApp.Context.Server.Transfer(Path.Combine(httpApp.Context.Request.RawUrl,"default.aspx").Replace("\\","/"));
}
}
catch (HttpException ex) {}
}
void OnEndRequest (object sender, EventArgs e) {}
public void Dispose() {} <add name="r" type="DefaultDocumentRedirect, mod" />
}
Your web.config file will need a HttpModules section adding the new module:
<httpModules>
</httpModules>