KILIÇ.NET

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() {}
}

Your web.config file will need a HttpModules section adding the new module:

<httpModules>

  <add name="r" type="DefaultDocumentRedirect, mod" />

</httpModules>