IIS7 Configuration API

IIS7 uses (nearly) standard .NET .config XML files for configuration. This is great and is one of the coolest features of IIS7 IMO. The metabase is gone (woohoo) and you can mix ASP.NET and IIS7 settings in a single web.config file. This means that you don’t have to adjust settings in two places and that you can deploy your ASP.NET application together with IIS7 configuration. That’s awesome.

How often have I wished in the past that I can configure Windows authentication in ASP.NET and IIS in a single step and without having to navigate GUIs. Like this:

<configuration>
 
<system.web>
   
<authentication mode=Windows />
 
</system.web>

  <system.webServer>
   
<security>
     
<authentication>
       
<anonymousAuthentication enabled=false />
       
<windowsAuthentication enabled=true />
     
</authentication>
   
</security>
 
</system.webServer>
</configuration>

To read or modify configuration you have several choices, notepad, the IIS GUI, a command line tool (appcmd.exe) or the IIS configuration API.

You can find the API in the Microsoft.Web.Administration.dll assembly located in the GAC or WindowsSystem32Inetsrv. The most obvious class to start with is called ServerManager – this gives you full access to the IIS7 configuration and you can easily navigate through most settings using the Sites, Applications, ApplicationDomains and ApplicationPools collections. Another not so obvious class is called WebConfigurationManager which also gives you access to configuration. What’s the difference and when to use which?

ServerManager is an administration (or design-time) API mostly useful for deployment and automated configuration. ServerManager is (currently) not designed for partial trust scenarios and some functionality requires elevated OS privileges.

WebConfigurationManager is a fast, light-weight runtime configuration API for applications, handlers and modules that need to read configuration settings. This is the one you want to use in your ASP.NET application code.

To get access to configuration you need a Configuration object. ServerManager features two methods called GetAdministrationConfiguration() and GetApplicationHostConfiguration() which return the Configuration object for the two machine wide config files (the Application class also has a method called GetWebConfiguration()). From there you usually call the GetSection() method and specify the configuration section you want to access using an XPath like expression, e.g. “system.webServer/directoryBrowse”. WebConfiguration also has a GetSection() method – the configuration returned here is always the one for the current application.

GetSection() returns a ConfigurationSection (derived) class from which you can read and write configuration attributes and, when using ServerManager, write the changes back to the config file. The following code changes configuration to allow directory browsing for an application:

Configuration config = app.GetWebConfiguration();

// weak typed
ConfigurationSection sectionBrowse = config.GetSection
  (
“system.webServer/directoryBrowse”);

sectionBrowse[“enabled”] = true;

Those of you who have looked at ASP.NET custom configuration sections know that you can provide a class that does the mapping between the object and XML worlds. This allows using strongly typed properties instead of string values to change attributes. The IIS7 configuration API uses a similar approach (but not the same). You can provide a ConfigurationSection derived class that gives you properties – but the actual schema of the configuration section (enums, default and required values, min/max values etc.) is specified in an XML file. The reason for that is (I believe) that configuration has to be usable from managed and unmanaged code – and the custom attribute approach to define schema would tightly-couple the configuration section to the CLR.

The schema definition for the <directoryBrowse> section looks like this:

<sectionSchema name=system.webServer/directoryBrowse>
 
<attribute name=enabled type=bool defaultValue=false />
 
<attribute name=showFlags type=flags defaultValue=Date, Time, Size, Extension>
   
<flag name=None value=0 /> 
    
<flag name=Date value=2 /> 
    
<flag name=Time value=4 />
   
<flag name=Size value=8 />
   
<flag name=Extension value=16 />
   
<flag name=LongDate value=32 /> 
  </attribute>
</sectionSchema>

You can find the complete schema file in Windowssystem32inetsrvconfigschema.

The corresponding configuration section class would look like this:

public class DirectoryBrowseSection : ConfigurationSection
{
 
public static string SectionName = “system.webServer/directoryBrowse”;

  public
bool Enabled
 
{
   
get { return (bool)base[“enabled”]; }
   
set { base[“enabled”] = (bool)value; }
 
}

  public EnumDirectoryBrowseShowFlags ShowFlags
 

   
get { return (EnumDirectoryBrowseShowFlags)base[“showFlags”]; }
   
set { base[“showFlags”] = (int)value;
  }
}

public enum EnumDirectoryBrowseShowFlags
{
 
None = 0,
 
Date = 2,
 
Time = 4,
 
Size = 8,
 
Extension = 16,
 
LongDate = 32
}

With such a strong typed wrapper, the configuration code looks more OO:

Configuration config = app.GetWebConfiguration();
DirectoryBrowseSection sectionBrowse = (DirectoryBrowseSection)
 
config.GetSection(
   
DirectoryBrowseSection.SectionName, 
    
typeof(DirectoryBrowseSection));

sectionBrowse.Enabled = true;

While technically there are already ConfigurationSection classes defined for all IIS7 and ASP.NET settings (in the Microsoft.Web.Management*.dll) – they are currently internal. Fortunately Kanwal from the IIS team posted a tool that generates configuration classes from the XML definition file. Simply point it at the IIS7 schema file and you will get an object model for all configuration groups and sections. Nice!

 

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s