0

I'd like to access IWebHostEnvironment.WebRootPath anywhere in the asp.net core mvc application. For instance, some random class deep in the class hierarchy. Is there a static class or some other method to do so?

I am aware that I can inject IWebHostEnvironment or that I can cache the value on the startup of the application. My question is strictly about accessing it without these methods.

AngryHacker
  • 59,598
  • 102
  • 325
  • 594
  • 1
    I don't think Microsoft devs permit accessing to the root path without first controller injection of `IWebHostEnvironment` or through `HttpContextAccessor` in static class – Codingwiz Feb 01 '23 at 17:21
  • I think "~" will always get you there... so maybe Server.MapPath("~") might give you the path. – pcalkins Feb 01 '23 at 20:40
  • I sometimes use AppContext.BaseDirectory for uploading files (I create directories there)... that should be where the .dll/exe is run. (which is outside of web path?) – pcalkins Feb 01 '23 at 20:50
  • 1
    `Server.MapPath("~")` has been deprecated and does not work in `Asp.Net Core`. [Check this StackOverflow](https://stackoverflow.com/questions/49398965/what-is-the-equivalent-of-server-mappath-in-asp-net-core) – Codingwiz Feb 01 '23 at 20:57
  • @pcalkins WebRootPath is the wwwroot folder. So AppContext won't work here. – AngryHacker Feb 01 '23 at 21:17
  • Is it possible that we hardcode the path in the configuration? I mean before we deploy the app, we modify the configuration... – Tiny Wang Feb 02 '23 at 02:42
  • No there's no static – davidfowl Feb 02 '23 at 05:24
  • 1
    in my case AppContext.BaseDirectory + "\wwwroot" gives you the path to my js, css, and lib folders... which is d:\inetpub\wwwroot\wwwroot. Not sure why you'd need that from inside the code, though. Generally if you're going to write files somewhere, you'd want it outside of webpath to help prevent deep links and ensure that user is authorized to download the file. I use "~/foldername/filename" for src values. (images, js, css...) which in my case from the server's perspective is d:\inetpub\wwwroot\wwwroot\foldername\filename – pcalkins Feb 03 '23 at 17:03

2 Answers2

0

I am aware that I can inject IWebHostEnvironment or that I can cache the value on the startup of the application. My question is strictly about accessing it without these methods.

No, you cannot. There's no static built in here with access to this information. You can create your own though.

davidfowl
  • 37,120
  • 7
  • 93
  • 103
0

You can achieve this y doing the following

In your Shared project or common project which is reference by the Web project add the below interface

public interface IApplicationContext
{
    public string BaseUrl { get; }
}

Then, in the web project add below code

public sealed class ApplicationContext : IApplicationContext
{
    private readonly IWebHostEnvironment _webHostEnvironment;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ApplicationContext(IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor)
    {
        _webHostEnvironment = webHostEnvironment;
        _httpContextAccessor = httpContextAccessor;
    }

    public string BaseUrl
    {
        get
        {

            var baseUrl = _webHostEnvironment.IsDevelopment() ? AppConstants.BaseUrl.FELocalHostBaseUrl :
                                                           _httpContextAccessor.HttpContext?.Request.BaseUrl();

            return baseUrl!;
        }
    }
}

Then, in you need to configure the dependency injection in your Startup.cs or any where that you configure DI as below

services.AddHttpContextAccessor();
services.AddScoped<IApplicationContext, ApplicationContext>();

Then you can inject the IApplicationContext in any service class constructor and access the baseUrl like below

public sealed class SecurityService
{
    private readonly IApplicationContext _applicationContext;

    public SecurityService(IApplicationContext applicationContext)
    {
        _applicationContext = applicationContext;
    }

    public async Task<ResponseResult> SendResetPasswordEmail(ForgotPasswordModel forgotPasswordModel, CancellationToken cancellationToken)
    {

        var baseUrl = _applicationContext.BaseUrl;

        return new ResponseResult();
    }
}
thanzeel
  • 431
  • 4
  • 12
  • Even though this is detailed, it does not answer the question. It was specifically asked to not use dependency injection or a cached value: `My question is strictly about accessing it without these methods`. Please read before answering. – Codingwiz Feb 06 '23 at 14:47