56

In my ASP.NET web app I'd like to look up the name it was given when it was created in IIS, which is unique to the server. I'd not interested in the domain name for the web site but the actual name given to the site in IIS.

I need to be able to do it reliably for IIS6 and 7.

To be clear I'm talking about the given name in IIS, not the domain name and not the virtual directory path.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Søren Spelling Lund
  • 1,622
  • 1
  • 13
  • 18
  • Can you elaborate a little more on the motivation? – Chuck Conway Oct 31 '09 at 16:20
  • 1
    I'm doing licensing for a web application I wrote and I need to make sure a license key is only used once per web app even on the same server. The web app works with multiple domain names assigned to the IIS site so binding the key to the domain name of the site won't do. In the same vain binding the key to the machine name won't do either as my app might be installed for multiple clients on the same machine. In short I need something uniquely identifying the IIS web site on a particular machine. Since IIS doesn't allow multiple sites with the same name I figure that's the way to go. – Søren Spelling Lund Oct 31 '09 at 16:25
  • I didn't mean to come off sounding condescending, I'm just curious why someone would want to do that. – Chuck Conway Oct 31 '09 at 16:25
  • I'm not sure about IIS7 but in IIS6 each site is given a unique siteId. I'd be surprised if this isn't the case in IIS7 – Chuck Conway Oct 31 '09 at 16:29
  • That's true and that's my fallback strategy. Only problem is that if you delete the site you'll get a new id, which would make the key useless. That's why I'd like to bind it to the site name instead. You're more likely to reuse that. – Søren Spelling Lund Oct 31 '09 at 16:33
  • 1
    Isn't it a duplicate for http://stackoverflow.com/questions/855176/get-iis-site-id-from-a-website – Moayad Mardini Oct 31 '09 at 18:13

6 Answers6

66

Update

As Carlos and others mentioned in the comments, it's better to use HostingEnvironment.SiteName since GetSiteName is not supposed to be used by users (According to the docs).

Old Solution

System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
m3kh
  • 7,881
  • 2
  • 31
  • 37
  • That's exactly what I was looking for. Thank you so much. Do you know whether it works for both IIS6 and 7? – Søren Spelling Lund Nov 02 '09 at 18:28
  • Sorry, I haven't tested it in IIS 6. – m3kh Nov 02 '09 at 18:47
  • 1
    I tested it for IIS 7/5.1 a few minutes age, I think it works for IIS 6 (90%). – m3kh Nov 02 '09 at 19:09
  • 17
    Isnt there just a HostingEnvironment.SiteName directly? Also, you could read the ServerVariable "InstanceName" that will give you that as well. – Carlos Aguilar Mares Jan 31 '11 at 18:02
  • 8
    This always returns 'Default Web Site' for me - and the online docs for ‘System.Web.Hosting.HostingEnvironment’ state ‘This property supports the ASP.NET infrastructure and is not intended to be used directly from your code’ – belugabob Apr 12 '12 at 08:43
  • 1
    @belugabob, Which version of IIS? Are you sure you are using another WebSite, not an VirtualDirectory under the "Default Web Site"? By the way, don't listen to documentation man. Check the CarlosAg's comment out, he is a member of IIS team. – m3kh Apr 14 '12 at 04:40
  • Yes - I was using a virtual directory (mostly because Visual Studio does it this way), but the sysadmin who deployed the app on the prodcution environment was using WebSites. I've since modified my code to behave as I want in either environment. I do use 'System.Web.Hosting.HostingEnvironment' in preference to 'System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName()’, for the reason stated above. – belugabob Apr 17 '12 at 12:03
  • 6
    Downvoted since, as per the [docs](https://msdn.microsoft.com/en-us/library/system.web.hosting.iapplicationhost.getsitename(v=vs.110).aspx), `Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName()` **should not be called** from your code. `Web.Hosting.HostingEnvironment.SiteName` should be used instead. – Dan Atkinson Feb 08 '18 at 13:03
  • This applies only for the .Net Framework, not Core or Standart. – Uladzimir Sharyi Feb 05 '20 at 09:16
  • I tried accessing this using the given solution but it is not correct but can't remove my vote yet. SiteName is the correct answer. If you need the virtual path name such https://aaa.com/bbb then you need to append ApplicationVirtualPath value (bbb) to SiteName (aaa.com). – SouthSun Jan 11 '22 at 11:08
20

As @belugabob and @CarlosAg already mentioned I'd rather use System.Web.Hosting.HostingEnvironment.SiteName instead of System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName() because IApplicationHost.GetSiteName method is not intended to be called directly! (msdn)

So you're better off using HostingEnvironment.SiteName property! (msdn)

I think this should be the correct answer in respect to the documentation ;)

Jan Köhler
  • 5,817
  • 5
  • 26
  • 35
  • 2
    Thanks for pointing this out. In my case System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName() worked, but then I ran into a weired "Type is not resolved for member" with serialization, that I was not able to track down. After switching to HostingEnvironment.SiteName it was gone. I assume it has something to do with MarshalByRefObject not compatible with Serialization. Just in case someone got hit by this as well, switching to HostingEnvironment.SiteName resolved that issue. – Marc Loeb Jun 30 '13 at 10:39
12

Here is a related post in retrieving the site Id.

Here some code that might work for you:

using System.DirectoryServices;
using System;

public class IISAdmin
{
   public static void GetWebsiteID(string websiteName)
   {
      DirectoryEntry w3svc = new DirectoryEntry("IIS://localhost/w3svc");

     foreach(DirectoryEntry de in w3svc.Children)
     {
        if(de.SchemaClassName == "IIsWebServer" && de.Properties["ServerComment"][0].ToString() == websiteName)
        {
           Console.Write(de.Name);
        }

     }

  }
  public static void Main()
  {
     GetWebsiteID("Default Web Site");
  }

}

Here's the link to the original post.

I'm not sure if it will work on IIS7, but if you install the IIS6 compatibility components for IIS7 it should work.

Community
  • 1
  • 1
Chuck Conway
  • 16,287
  • 11
  • 58
  • 101
9

You are looking for ServerManager (Microsoft.Web.Administration) which provides read and write access to the IIS 7.0 configuration system.

Iterate through Microsoft.Web.Administration.SiteCollection, get a reference to your website using the Site Object and read the value of the Name property.

// Snippet        
using (ServerManager serverManager = new ServerManager()) { 

var sites = serverManager.Sites; 
foreach (Site site in sites) { 
         Console.WriteLine(site.Name); // This will return the WebSite name
}

You can also use LINQ to query the ServerManager.Sites collection (see example below)

// Start all stopped WebSites using the power of Linq :)
var sites = (from site in serverManager.Sites 
            where site.State == ObjectState.Stopped 
            orderby site.Name 
            select site); 

        foreach (Site site in sites) { 
            site.Start(); 
        } 

Note : Microsoft.Web.Administration works only with IIS7.

For IIS6 you can use both ADSI and WMI to do this, but I suggest you to go for WMI which is faster than ADSI. If using WMI, have a look at WMI Code Creator 1.0 (Free / Developed by Microsoft). It will generate the code for you.

HTH

ntze
  • 126
  • 1
  • 5
0

You can use below code

private string WebsiteName()
{
    string websiteName = string.Empty;
    string AppPath = string.Empty;
    AppPath = Context.Request.ServerVariables["INSTANCE_META_PATH"];
    AppPath = AppPath.Replace("/LM/", "IIS://localhost/");
    DirectoryEntry root = new DirectoryEntry(AppPath);
    websiteName = (string)root.Properties["ServerComment"].Value;
    return websiteName;
}
0

You will need to do the ServerManager.OpenRemote("serverName") first when connecting to a remote server.

Basically doing something like this

            using (ServerManager srvMgr = ServerManager.OpenRemote("serverName"))
            {

            }

see msdn help

pungggi
  • 1,263
  • 14
  • 25