I figured out why.
This misbehavior can be reproduced on IIS 5.0 (Windows 2000) and IIS 5.1 (Windows XP Pro). It does not effect VS's development server nor IIS 6.0.
When IIS 5.x sees a URL like this "/webservices/helloworld.asmx/js", it splits them into token and iterates through them from left to right. For each token, it checks to see if it ends as a string that matches an extension mapping. As soon as it finds it, it stops. At this point, before IIS forward the request to ASP.Net's ISAPI extension, it takes that finding and creates two server variables: URL and PATH_INFO.
For example, the following URL:
"/webservices/helloworld.asmx/js"
would cause IIS to define the following server variables:
SERVER_VARIABLE["URL"]: "/webservices/helloworld.asmx"
SERVER_VARIABLE["PATH_INFO"]: "/webservices/helloworld.asmx/js"
Similarly, a URL like this:
"/nonexistent.aspx/helloworld.asmx/js"
would cause IIS to define the following server variables:
SERVER_VARIABLE["URL"]: "/nonexistent.aspx"
SERVER_VARIABLE["PATH_INFO"]: "/nonexistent.aspx/helloworld.asmx/js"
When you turn on IIS 5.x wildcard extension mapping, this logic never gets executed. Instead, IIS defines the URL server variable the same way it defines PATH_INFO (i.e. nothing is stripped out).
ASP.Net does not like this. Without URL rewriting, ASP.Net doesn't know how to handle the request "/webservices/helloworld.asmx/js". Because of this, ASP.Net forwards the request to the FileNotFound http handler which displays the 404 error page we see.
Again, this only applies to IIS 5.x and not IIS 6.0. IIS 6.0 seems to have reworked this logic in the expected way.
To solve this problem, create a file called IIS5XWildCardExtensionFix.cs and place it in your App_Code folder:
using System;
using System.Web;
public class IIS5XWildCardExtensionFix : IHttpModule
{
public IIS5XWildCardExtensionFix() { }
public void Dispose() { }
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(OnBeginRequest);
}
private void OnBeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
HttpContext context = app.Context;
string path = context.Request.Path;
int asmx = path.IndexOf(".asmx/", StringComparison.OrdinalIgnoreCase);
if (asmx >= 0)
context.RewritePath(
path.Substring(0, asmx + 5),
path.Substring(asmx + 5),
context.Request.QueryString.ToString());
}
}
Add the following line to in your web.config file in the HttpModules tag:
<add name="IIS5XWildCardExtensionFix" type="IIS5XWildCardExtensionFix" />
This code inserts the missing logic using ASP.Net's HTTP Module framework.
This code is derived from djMax's post.
-David