0

In my MVC app I want to get website's physical path on IIS server. This old post is about it, but I'm using a newer version of IIS (10.0.19041.1). Is there another way of accomplishing this task? I was trying the accepted solution from the above mentioned post, but it throws me an exception System.NullReferenceException: 'Object reference not set to an instance of an object.' site was null..

using Microsoft.Web.Administration;
//...

    int iisNumber = 2;        
   using (ServerManager serverManager = new ServerManager())
        {
            var site = serverManager.Sites.Where(s => s.Id == iisNumber).SingleOrDefault();
            var applicationRoot = site.Applications.Where(a => a.Path == "/").SingleOrDefault(); //here I get the exception
            var virtualRoot = applicationRoot.VirtualDirectories.Where(v => v.Path == "/").SingleOrDefault();
            Console.WriteLine(virtualRoot.PhysicalPath);
            System.Diagnostics.Debug.WriteLine("***************************************path to IIS website: " + virtualRoot.PhysicalPath + "***************************************");
        }

My website properties: enter image description here

Ionut
  • 724
  • 2
  • 9
  • 25
  • is your IIS has websites other than default registered? try check the content of `serverManager.Sites` first, without the `where`. – Bagus Tesa May 18 '22 at 08:44
  • Yes, my IIS has another site than default registered. I was trying ` var applicationRoot = site.Applications.SingleOrDefault();` as you suggested, but I'm still getting the exception... – Ionut May 18 '22 at 08:46
  • how many? have you tried to enumerate `serverManager.Sites`? i have no idea why the answer in your link always check for id number 2 though [the docs](https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.administration.site.id?view=iis-dotnet#microsoft-web-administration-site-id) said its internal id for a site in IIS. – Bagus Tesa May 18 '22 at 08:53
  • its the `site` that was null - which caused by `where` clause results empty list and then `SingleOrDefault` returns null because there is nothing to be returned from the list. thats why i suggest iterate `serverManager.Sites` and see what it has. – Bagus Tesa May 18 '22 at 08:53
  • I have 2 sites (the default one, and my published app). My website has the ID=2. I will edit my question with the properties of my site. – Ionut May 18 '22 at 08:56
  • Can't you use the request object itself, since you're in MVC anyways. So you could call `Request.PhysicalApplicationPath`, which should return what you are looking for without going over a proxy object like IIS Server Manager – Marco May 18 '22 at 09:06
  • @Macro, what if have multiple websites? How would them be differentiated? I'm trying to get like this: `string path = Request.PhysicalApplicationPath +@"\";` but I get the error: CS0117 'Request' does not contain a definition for 'PhysicalApplicationPath' – Ionut May 18 '22 at 09:20
  • @Ionut, you can use `HostingEnvironment.Map(path)` (from `System.Web.Hosting` namespace) if you are in the web app itself and wanted to access certain directory path. i'm sure the `ServerManager` is meant to be used by application outside of IIS enviroment - imagine your app kills itself using that api by editing `web.config`. this is why i wanted you to enumerate the `Sites`, there might be protection in place to avoid your website reconfiguring itself then kills itself midway. – Bagus Tesa May 18 '22 at 11:08
  • I wrote this: `System.Web.Hosting.HostingEnvironment.MapPath(@"C:\ReportDesigner\server\publish"); ` , but I get an exception: `System.ArgumentException: 'The relative virtual path 'C:/ReportDesigner/server/publish' is not allowed here.'` when I debug the project. Why is this happening? – Ionut May 18 '22 at 11:40

0 Answers0