ASP.NET Core Server.MapPath equivalent How to access the absolute path to the application content files in ASP.NET Core Application just like we did with Server.MapPath using IWebHostEnvironment

How to fix the "No executable found matching command dotnet-ef" error in Visual Studio with .NET Core

If you've stumbled upon this post there's a high chance that you're a seasoned ASP or ASP.NET Web Developer who is trying to find an alternative to the good old Server.MapPath method in ASP.NET Core. if I'm right, look no further, because you came to the right place.

As you most likely already know, the Server.MapPath method is a typical approach that we could use since classic ASP and ASP.NET Web Forms and MVC versions up to and including 5. Here's a typical way to use it:

That was a quick and effective way to access the files that we've put in the <ApplicationRoot>/App_Data/docs/ folder... and the best part of it was that it worked right out of the box, no matter if we were in Debug or Production environments.

Unfortunately this method has been removed in ASP.NET Core: how can we replace it? Well, luckily enough we have a number of possible alternatives. In this post we'll take a look at the two of them which I like the most.

IWebHostEnvironment

One of the services that's included by default when you create an ASP.NET Core application is the IWebHostEnvironment interface (which replaced the previous IHostingEnvironment that was used up-to-date until ASP.NET Core 3.0). This interface can be instantiated whithin any Controller using the standard .NET Core Dependency Injection pattern in the following way:

As we can see, the service has two properties of particular interest: ContentRootPath and WebRootPath.

  • ContentRootPath resolves to the application's base path: this is the location of the web.config, project.json, and other configuration files.
  • WebRootPath gets the app's physical publishing path, which in an ASP.NET Core Application typically is the wwwroot folder.

This basically means that we can get our /App_Code/Docs path in the following way:

That's great, isn't it?

As a matter of fact, it definitely is: but what if we don't want to instantiate the IWebHostEnvironment interface in all of our application's Controller, or if we want to use such a convenient way to determine our app's physical paths outside from our Controllers (such as, for example, within a helper class)?

Well, here's a quick and effective method to allow that using AppDomain.CurrentDomain.

AppDomain.CurrentDomain

If you don't want to instantiate the IWebHostEnvironment interface in all of your Controllers, and/or if you want to access those properties from non-Controller classes, we can "store" them for later use thanks to a neat built-in feature of the AppDomain static class, which represents the application domain (the isolated environment where applications execute). Such class features a convenient CurrentDomain property with a SetData / GetData pair of methods that can be used to store arbitrary values within that secluded context.

This basically means that we can add the following line(s) of code at the end of the Configure() method of our app's Startup.cs file:

And then retrieve them from within any class (including, yet not limiting to, Controllers and Views) in the following way:

This simple but effective technique can be further exploited to create a static helper method that will allow us to have the same functionality as the good old Server.MapPath:

And then use it in the following way:

Here we go!

Conclusions

That's it, at least for now: we hope that this post will help those ASP.NET Core developers that are looking for a way to replace the "classic" Server.MapPath method they were used to work with.

If you want to know more about .NET Core and Angular check out the ASP.NET Core 5 and Angular book, available as paperback and e-book.

 

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

6 Comments on “ASP.NET Core Server.MapPath equivalent How to access the absolute path to the application content files in ASP.NET Core Application just like we did with Server.MapPath using IWebHostEnvironment

  1. Thanks! I recently returned to .Net (after years) and now with Core, many things have to be upgraded.

    I updated your MyServer class as the path returned (under Windows) had a mix of slashes and backslashes. I ended up going a simple Replace and now the full path is proper.

    return Path.Combine((string)AppDomain.CurrentDomain.GetData(“ContentRootPath”), path.Replace(‘/’, ‘\’));

  2. This documentation refers to a field called ‘env’. Where does this field come from? My asp .net core 6.0 program.cs does not recognize it.

    1. If you’re using ASP.NET Core 6 with the new hosting model (without Startup.cs file), your env variable equivalent (originally a parameter of the Configure method in the Startup.cs class) is the builder.Environment property (in the Program.cs file).

  3. Groovy.
    Now, how does one get the content pointed to by the link, in my case a .PDF, into a view? Not the PDF – just the link. id \myserver\pdffoco\my.pdf.
    thanx,
    Doug

    1. It’s literally explained in the post.

      var contentRootPath = (string)AppDomain.CurrentDomain.GetData(“ContentRootPath”);
      var webRootPath = string)AppDomain.CurrentDomain.GetData(“WebRootPath”);

      With these variables, you can just do something like $”{contentRootPath}/my.pdf” or the equivalent.

  4. Thank you.
    What I meant to ask is how do we access the web hosting properties from inside a view.
    First we need to inject them into the view…
    @inject IWebHostEnvironment environment

    Then we can access the “directly”
    @environment.WebRootPath.ToString()) @Html.DisplayFor(model => model.Link))

    Sorry, Ryan. I’ll try to be a little more vague with my next question. 😜

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.