IIS: How to get the Metabase path?

Ian Boyd picture Ian Boyd · Apr 26, 2010 · Viewed 19.1k times · Source

i'm trying to get the list of mime types known to an IIS server (which you can see was asked and and answered by me 2 years ago). The copy-pasted answer involves:

GetObject("IIS://LocalHost/MimeMap") msdn

GetObject("IIS://localhost/mimemap") KB246068

GetObject("IIS://localhost/MimeMap") Scott Hanselman's Blog

new DirectoryEntry("IIS://Localhost/MimeMap")) Stack Overflow

new DirectoryEntry("IIS://Localhost/MimeMap")) Stack Overflow

New DirectoryServices.DirectoryEntry("IIS://localhost/MimeMap") Velocity Reviews


You get the idea. Everyone agrees that you use a magical path iis://localhost/mimemap. And this works great, except for the times when it doesn't.

The only clue i can find as to why it fails, is from an IIS MVP, Chris Crowe's, blog:

string ServerName = "LocalHost";
string MetabasePath = "IIS://" + ServerName + "/MimeMap";
    // Note: This could also be something like
    // string MetabasePath = "IIS://" + ServerName + "/w3svc/1/root";

DirectoryEntry MimeMap = new DirectoryEntry(MetabasePath);

There are two clues here:

  1. He calls iis://localhost/mimemap the Metabase Path. Which sounds to me like it is some sort of "path" to a "metabase".
  2. He says that the path to the metabase could be something else; and he gives an example of what it could be like.

Right now i, and the entire planet, are hardcoding the "MetabasePath" as

iis://localhost/MimeMap

What should it really be? What should the code be doing to construct a valid MetabasePath?


Note: i'm not getting an access denied error, the error is the same when you have an invalid MetabasePath, e.g. iis://localhost/SoTiredOfThis

Answer

Kev picture Kev · Apr 27, 2010

If you're working with the IIS config of your local machine i.e. your code and IIS are on the same box then it's sufficient to specify:

IIS://Localhost/mimemap

The IIS: portion is also known as a moniker in OLE parlance.

If you open the IIS6 metabase file (C:\Windows\System32\inetsrv\metabase.xml) you'll find a large 'blob' of XML. This is in fact a flattened out tree structure.

Paths in the metabase are represented by Location attributes.

The moniker IIS://localhost maps to the Location path /LM which is effectively the tree root.

The moniker IIS://localhost/MimeMap maps to the Location path /LM/MimeMap.

If your code is accessing the metabase on remote machines then instead of specifiying IIS://localhost/[path], one would specify IIS://[RemoteMachineName]/[path]. This is what Chris Crowes comment means.

IIS://localhost/MimeMap is also the master Mime Type list. All sites inherit this list (the IIS Metabase relies heavily on inherited properties).

If you wanted to override the Mime types for a specific site then you'd modify:

IIS://localhost/W3SVC/[iisnumber]/ROOT/MimeMap

It's useful to open up the IIS metabase file and have a dig around to understand what's going on under the bonnet.

Update:

To answer your question about why you can create a DirectoryEntry object where the path is invalid, DirectoryEntry is a general purpose wrapper object used to bind against different types of ADSI providers such as IIS, LDAP and WinNT. It permits creation of DirectoryEntry objects where there may not necessarily be a matching object at the path specified. Some ADSI provider operations may require this capability.

There is a static method on DirectoryEntry called Exists that you can use to test for the existence of objects. For example:

// Does Default Website exist?
if(DirectoryEntry.Exists("IIS://localhost/w3svc/1"))
{
  // Do work...
}