Using Vista...
I have a script that uses ADSI to set ScriptMaps on an IIS Website. It's javascript, run within cscript.exe, and the code looks something like this:
var web = GetObject("IIS://localhost/W3SVC/1");
var maps = web.ScriptMaps.toArray();
map[maps.length] = ".aaa,c:\\path\\to\\isapi\\extension.dll,1,GET,POST";
web.ScriptMaps = maps.asDictionary();
web.SetInfo();
When I look in the IIS Manager after running the script, I can see the new entry in the list of Handler Mappings. It has a weird name "AboMapperCustom-43155", which I understand comes from the IIS7 compatibility layer for ADSI.
If, in IIS Manager, I then remove those Handler Mappings, then run another ADSI script to query the ScriptMaps property, the retrieved ScriptMaps in the script still lists the entry that was just removed. The results in the ADSI script don't agree with the list of "Handler Mappings" shown in the IIS Manager.
This persists even after a start/stop of IISADMIN and W3SVC.
Is this expected behavior? ADSI is supported as a "compatibility mode" in IIS7. Is this an artifact of that?
I believe that if the Handler Mapping is removed from IIS MAnager, then it is really gone, even though it still gets returned from an ADSI query.
Can anyone offer any clarification on this?
When you add a 'scriptmap' using the ADSI compatibility bits (using the Default Web Site for the sake of argument), this adds a handler mapping to the applicationHost.config
file for the site at:
<location path="Default Web Site">
<system.webServer>
<handlers>
<add name="AboMapperCustom-12345678" ... />
</handlers>
</system>
</location>
When you delete the handler mapping in the IIS7 manager, instead of removing the mapping from the applicationHost.config
file and the section shown above, a web.config
file is added to the root of the site with the following:
<configuration>
<system.webServer>
<handlers>
<remove name="AboMapperCustom-12345678" />
</handlers>
</system>
</configuration>
When getting the configuration for a website using the new managed Microsoft.Web.Administration
.NET API you can read the config at different levels, for example:
1: Read the configuration at the applicationHost.config
or APPHOST level
ServerManager serverManager = new ServerManager();
var site = serverManager.Sites.Where(s => s.Id == 1).SingleOrDefault();
Configuration siteConfig = serverManager.GetApplicationHostConfiguration();
ConfigurationSection handlersSection =
siteConfig.GetSection("system.webServer/handlers", site.Name);
ConfigurationElementCollection handlersCollection =
handlersSection.GetCollection();
foreach (var item in handlersCollection)
{
Console.WriteLine(item.Attributes["name"].Value);
}
In the example above, even though you've removed the mapping, it will still be listed when iterating the handler mapping collection. This because you've asked for the configuration at the application host level. Any web.config
files that exist in the site root or below will not be read and their handler <add/>
and <remove/>
directives will not be included.
2: You can read the configuration that is specific to a site (or subfolder in a site):
ServerManager serverManager = new ServerManager();
Configuration siteConfig = serverManager.GetWebConfiguration("Default Web Site");
ConfigurationSection handlersSection =
siteConfig.GetSection("system.webServer/handlers");
ConfigurationElementCollection handlersCollection =
handlersSection.GetCollection();
foreach (var item in handlersCollection)
{
Console.WriteLine(item.Attributes["name"].Value);
}
This will also read the site web.config
file and will return a handler mapping list that accounts for the <add/>
and <remove/>
directives specified in the web.config
.
This is what the IIS7 Manager application is doing when you are viewing and modifying handler mappings. It is adding and removing handlers by creating (if necessary) a web.config
file in the site root folder (or subfolders) and adding the requisite <add/>
and <remove/>
at this level.
The IIS6 compatibility layer appears to operate solely at the applicationHost.config
APPHOST level (option 1 above) which is why you're seeing these differences.
Is it a bug? I'm not sure it is because ultimately ADSI was never web.config
aware in the first place. Also MS would have to add a new method or flag to allow you to specify at which level you really want to make these 'scriptmap' changes and that may mean breaking and testing the ADSI components, which in turn may introduce bugs. The behaviour is there to simulate modifying the old IIS6 metabase, and applicationHost.config
is in effect analagous to the metabase so you could argue, rightly or wrongly, it's doing the right thing.