my first post on IIS 7.0......lot to explore yet :)

Recently I have started exploring IIS 7.0 and one word that can express my feeling is "WOW!". IIS 7.0 is way ahead of all the previous versions of IIS. I have worked extensively with IIS 5.0/5.1/6.0 and I can say for sure, IIS 7.0 is completely in a different league of its own. There are many new features embedded in it which were not present in the earlier versions. Important ones are like Integrated Pipeline, Automatic Application Pool Isolation, Extensibility, Modularization etc. I would love to go on talking about what IIS 7.0 is and what all customizations you can go on doing with it. It has opened a wide array of opportunities for Web Admins and developers alike. I am pretty sure the Web Hosters would love it. You have the option to delegate Admin privileges to the users for specific sites/applications hosted on the Web server.

To cut the long story short I will not go into the details of the various features and come to the topic of this blog. In case you are interested to know more about IIS 7.0 just visit www.iis.net and there are some really cool articles/blogs/downloads waiting for your eyes to be laid upon them :-)

I started playing with IIS 7.0 and found that it is really interesting for developers, native and managed based alike.

Here I will show ways in which you can determine various information about Web Sites, Virtual Directories, Applications etc. through simple code written in C#. You can use the functionality to get on to advanced usage. My main motive is to show that things have become really simple with IIS 7.0.

ApplicationHost.config file has become what metabase.xml in IIS 6.0 and metabase.bin in IIS 5.0/5.1 were meant for. Although they are not exactly the same but they serve the same purpose.

Here I have the code (Ignore the formatting/minor errors if any ;-)) which reads the ApplicationHost.config file based on the schema from IIS_Schema.xml (By default, it will be under the folder %Systemdrive%\Windows\System32\inetsrv\config\schema.

What is worth noting is that reading configuration data is similar to reading web.config in ASP.Net. In fact IIS 7.0 is very tightly  coupled with ASP.Net now.

Microsoft.Web.Administration namespace contains many useful features to programmatically get data for IIS 7.0 configuration. Explore it and you will find lot many interesting options available.

Here I have added some relevant section for my code from the above config file. Notice how you can programmatically fetch data from the ApplicationHost.config file.

ApplicationHost.config snippet:

<configuration>

............

       <configSections>
               <sectionGroup name="system.applicationHost">
                         .........
                         <section name="sites" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
                         .........
               </sectionGroup>

        ...........
       </configSections>

.....

<system.applicationHost>
.............
.............

          <sites>
                 ............
               

              <site name="test" id="2" serverAutoStart="false">
                       <application path="/">
                              <virtualDirectory path="/" physicalPath="E:\Visual Studio Express\testwebsite" />
                              <virtualDirectory path="/aspnettest" physicalPath="E:\Visual Studio Express\aapnetlearn" />
                        </application>
                      
                ...........
                </site>

              ..................
               
          </sites>
.............
</system.applicationHost>

<Code Snippet>

 using System;
 using System.Collections.Generic;
 using System.Text;
 using Microsoft.Web.Administration;
  
 namespace IIS7codeDemo
 {
     class Program
     {
        static void Main(string[] args)
        {
            ServerManager sm = new ServerManager();
            Configuration config = sm.GetApplicationHostConfiguration();  // <--- Reading the ApplicationHost.config file
            ConfigurationSection cfgSection = config.GetSection("system.applicationHost/sites"); // <-- Picking up Web sites section in the ApplicationHost.config file.
            ConfigurationElementCollection configEleColl0 = cfgSection.GetCollection(); // <-- Since various sites are collection elements under the /Sites section, we read the whole Site collection.
           
            //Iterating through each collection
            foreach (ConfigurationElement cfgElement0 in configEleColl0) // <--- <sites>....</sites>
            {
                Console.WriteLine("Site Name:  " + cfgElement0.GetAttributeValue("name"));
                Console.WriteLine("===============================");
                ConfigurationElementCollection configEleCol1 = cfgElement0.GetCollection(); // <--- <application>....</application>
              
                foreach (ConfigurationElement cfgElement1 in configEleCol1)
                {
    //              Console.WriteLine("Application Virtual Path in " + cfgElement0.GetAttributeValue("name")+":" + cfgElement1.GetAttributeValue("path"));
  
                    ConfigurationElementCollection configEleCol2 = cfgElement1.GetCollection(); // <--- <virtualDirectory>....</virtualDirectory>
  
                    foreach (ConfigurationElement cfgElement2 in configEleCol2)
                    {
                        Console.Write("Virtual Path: " + cfgElement1.GetAttributeValue("path")+ cfgElement2.GetAttributeValue("path")); // <--- Reading Virtual Path attribute
                        Console.WriteLine("    " + "Physical Path: " + cfgElement2.GetAttributeValue("physicalPath"));  // <--- Reading Physical Path attribute
                    }
                }
                Console.Write("\n\n");
            }
            Console.ReadLine();
        }
    }
  

Here we have queried for the Web site, Virtual Directory etc.

Output:

Site Name: Default Web Site
===============================
Virtual Path: // Physical Path: %SystemDrive%\inetpub\wwwroot
Virtual Path: /widget/ Physical Path: C:\inetpub\wwwroot\widget
Virtual Path: /widget/vd3 Physical Path: E:\CPP
Virtual Path: /blogsite/ Physical Path: E:\Visual Studio Express\New Folder
Virtual Path: /App1/ Physical Path: D:\test
Virtual Path: /widget/vd3/app6/ Physical Path: c:\Inetpub

You can query for any other information like Application pools, bindings, modules, handler etc. In fact you can get most of the information that is present in ApplicationHost.config file programmatically.

Another way you can  get the above information is via classes available in the Microsoft.Web.Administration namespace.

Here is another code snippet which gets the above information not by reading the ApplicationHost.config file but by using managed .Net classes available for such queries.

Code Snippet:

 using System;
 using System.Collections.Generic;
 using System.Text;
 using Microsoft.Web.Administration;
  
 namespace IIS7Demo
 {
     class Program
     {
        static void Main(string[] args)
        {
            ServerManager mgr = new ServerManager();
            SiteCollection allSites = mgr.Sites;
            
            foreach (Site site in allSites)
            {
                Console.WriteLine(site.Name.ToString());
                Console.WriteLine("--------------");
                ApplicationCollection allApplications = site.Applications;
  
                foreach (Application app in allApplications)
                {
                    VirtualDirectoryCollection vdc = app.VirtualDirectories;
  
                    foreach (VirtualDirectory virDir in vdc)
                    {
                        string temp = app.Path + virDir.GetAttributeValue("path") + "     Loc: " + virDir.GetAttributeValue("physicalPath");
                        string output = temp.Replace("//", "/");
                        Console.WriteLine(output);
                    }
  
               }
  
                Console.WriteLine("================\n\n");
            }
            Console.ReadLine();
        }
  
    }
  

Till next time...