Sorry for a noob question, but it seems I can't get Server.MapPath from Controller. I need to output json file list from images folder at wwwroot. They are is at wwwroot/images. How can I get a reliable wwwroot path?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using www.Classes;
using System.Web;
namespace www.Controllers
{
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
FolderScanner scanner = new FolderScanner(Server.MapPath("/"));
return scanner.scan();
}
}
}
Server.MapPath seems not available from System.Web namespace.
Project is using ASP.NET 5 and dotNET 4.6 Framework
You will need to inject IWebHostEnvironment into your class to have access to the ApplicationBasePath property value: Read about Dependency Injection. After successfully injecting the dependency, the wwwroot path should be available to you. For example:
private readonly IWebHostEnvironment _appEnvironment;
public ProductsController(IWebHostEnvironment appEnvironment)
{
_appEnvironment = appEnvironment;
}
Usage:
[HttpGet]
public IEnumerable<string> Get()
{
FolderScanner scanner = new FolderScanner(_appEnvironment.WebRootPath);
return scanner.scan();
}
Edit: IHostingEnvironment has been replaced by IWebHostEnvironment in later versions of asp.net.
I know this has already been answered, but it has given me different results depending on my hosting environment (IIS Express vs IIS). The following approach seems to work for all hosting environments nicely if you want to get your wwwroot path (see this GitHub issue).
For example
private readonly IHostingEnvironment _hostEnvironment;
public ProductsController(IHostingEnvironment hostEnvironment)
{
_hostEnvironment = hostEnvironment;
}
[HttpGet]
public IEnumerable<string> Get()
{
FolderScanner scanner = new FolderScanner(_hostEnvironment.WebRootPath);
return scanner.scan();
}
For those who deploy to Azure and come into this error. What I did was a work around for it, I haven't tried to figure out why environment of Azure is different than local IIS.
Here is my work around:
if (string.IsNullOrWhiteSpace(_environment.WebRootPath))
{
_environment.WebRootPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
}
Of course you will need:
private IHostingEnvironment _environment;
public OnboardingController(IHostingEnvironment environment)
{
_environment = environment;
}
There is another way to implement this right from startup. It is not exact solution to this case per se, but I modified it to suit my need. We need a singleton for this. This is a startup class with environment injection.
namespace www
{
public class Startup
{
private IHostingEnvironment _env;
public Startup(IHostingEnvironment env)
{
_env = env;
Environment.rootPath = env.WebRootPath;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
app.UseMvc();
}
}
}
The environment variables I was looking for is there, IHOstingEnvironment. But for my purpose, I need to make Environment class like this to easily access all environment items from all project. This singleton will provide data to configuration, environment, and many other thing. But for this thread, I would just put one rootPath property.
namespace www.Utilities
{
public class Environment
{
private static Environment instance;
private static String _rootPath;
private Environment() { }
public static Environment Instance
{
get
{
if (instance == null)
{
instance = new Environment();
}
return instance;
}
}
public static string rootPath
{
set
{
_rootPath = value;
}
get
{
return _rootPath;
}
}
}
}
As I have accepted Oluwafemi's answers, I'll keep it that way, since he led me to this. But I think this is the better way to access environment variables throughout the project
Related
I'm migrating from netcore2.1 to netcore3.1. I have a service where I need to create an IServiceProvider and inject IWebHostEnvironment (I used to inject IHostingEnvironment in netcore2.1). The code used to just create a new Microsoft.Extensions.Hosting.Internal.HostingEnvironment instance but that class doesn't contain WebRootPath anymore. I fetched git repo and tried to look for implementations of IWebHostEnvironment but it seems that the only implementation is internal to aspnetcore which is of no use.
Is there a possibility to create an instance of IWebHostEnvironment somehow?
Daniel
Hi You can access WebRoot Path using in Core 3.1
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
private readonly IWebHostEnvironment _hostingEnv;
public HomeController(IWebHostEnvironment hostingEnv)
{
_hostingEnv = hostingEnv;
}
private Void GetWebRoot()
{
var webRootPath = _hostingEnv.WebRootPath;
}
}
Can you try this, upvote if it helps
In .NET framework I would have just used Server.MapPath(). In .NET Core 2.2, I understand I should be using IHostingEnvironment. But every example I can find seems to assume I'm using it in a controller. And these examples say to inject IHostingEnvironment in the controller. But...
In my case, I am using some *.json files as data repositories. I am creating an independent Data Access class that can be called from multiple upstream locations. I'm not grasping how to inject IHostingEnvironment into this class without impacting the upstream callers. The idea is, if we someday swap out the .json files for a SQL table, then we want to only make changes to the Data Access class, and not to any of the sources which call it.
So, how, in the Data Access class, can I map a path to a local .json file?
namespace DataAccess
{
public class Repository
{
private readonly string _connStringName;
public Repository(string connStringName)
{
_connStringName = connStringName;
}
public IEnumerable<T> GetList<T>()
{
IEnumerable<T> entities;
using (StreamReader r = new StreamReader(_connStringName)) // <---- ??
{
string json = r.ReadToEnd();
entities = JsonConvert.DeserializeObject<List<T>>(json);
}
return entities;
}
}
}
This line:
using (StreamReader r = new StreamReader(_connStringName))
wants to map a path to IIS Express, which I understand. But I need it to map a path to the relative location of the file.
Thanks!
EDIT:
Maybe I am doing this wrong? This is how I was trying to follow the examples I saw:
public class Repository
{
private readonly string _connStringName;
private IHostingEnvironment _hostingEnvironment;
public Repository(string connStringName, IHostingEnvironment environment)
{
_connStringName = connStringName;
_hostingEnvironment = environment;
}
// rest of the class
}
If I do it this way, every upstream location that creates an instance of Repository now has to pass `IHostingEnvironment' into it.
EDIT 2:
How Repository is being used.
public static class Customers
{
private static readonly string _connStringName = "customer.json";
public static string Get()
{
DataAccess.Repository repository = new DataAccess.Repository(_connStringName);
List<Customer> customers = repository.GetList<Customer>().ToList();
return JsonConvert.SerializeObject(customers);
}
}
In .NET Core you can register your dependencies to be injected at startup.
If you do it this way, you will need to:
inject Repository into Customers.
pass Repository dependencies in Startup
// Startup.cs
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services, IHostingEnvironment env)
{
// [2]
var connectionString = "customer.json"; // or get from a config file
services.AddSingleton<Repository>(new Repository(connectionString, env));
}
// ...
}
public class Customers
{
private Repository _repository;
public Customers(Repository repository)
{
// [1]
_repository = repository;
}
public string Get()
{
// you can use _repository here without passing stuff in
}
}
public class Repository
{
private IHostingEnvironment _env;
public Repository(string connectionString, IHostingEnvironment env)
{
_env = env;
}
}
.NET Core Dependency Injection - https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
I'm trying to get the current directory path from server side code. In asp.net we used HttpContext.Current.Server.MapPath to get the path. But it's different with asp.net core we're supposed to use IHostingEnvironment to get the path. As far as I know it's only used in the StartUp class and in Controllers but what I'm trying to do is use it in a server side class. How do I do that?
I've tried to pass the IHostingEnvironment value to the constructor of a server side class but it sets it to null. Nothing else was added in the StartUp class.
I also tried to look for any help on the internet and couldn't believe there was nothing that can help me to set the value in a server side class.
Here's an example of my code:
public class PathHelper
{
private static IHostingEnvironment _hostingEnvironment;
public PathHelper(IHostingEnvironment environment)
{
_hostingEnvironment = environment;
}
public static string RootPath
{
get
{
return _hostingEnvironment.ContentRootPath;
}
}
The error I get is
null reference at the constructor level.
This is not the best option, but this is what I currently doing right now.
I pass the IHostingEnvironment to static class to be used globally and init on Configure method in Startup.cs.
public static class Context
{
public static IHostingEnvironment HostingEnvironment;
}
Assign on Configure method in Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
//.....
namespace.Context.HostingEnvironment = env;
}
I've just recently switched over from ASP.NET MVC to using .Core 2 and I can't figure out how to get the current URL in Core. I could get it easily enough using the Request in previous asp.net versions, but since that's no long valid in .Net Core I'm at a loss.
I haven't been able to find any way from my google searching as of now.
Any help is appreciated. Thanks!
In the ConfigureServices method of your Startup.cs file, add the line:
services.AddHttpContextAccessor();
and you will now have access to the IHttpContextAccessor interface throughout your code when using dependency injection.
Usage as follows:
public class CustomerRepository
{
private readonly IHttpContextAccessor _context;
public CustomerRepository(IHttpContextAccessor context)
{
_context = context;
}
public string BaseUrl()
{
var request = _context.HttpContext.Request;
// Now that you have the request you can select what you need from it.
return string.Empty;
}
}
Hope this answers your question :)
Try:
public class Startup {
public Startup(IConfiguration configuration, IHostingEnvironment env) {
Configuration = configuration;
HostingEnvironment = env;
var url = configuration[WebHostDefaults.ServerUrlsKey];
}
Please note that you can get more than one url.
Sorry for a noob question, but it seems I can't get Server.MapPath from Controller. I need to output json file list from images folder at wwwroot. They are is at wwwroot/images. How can I get a reliable wwwroot path?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using www.Classes;
using System.Web;
namespace www.Controllers
{
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
FolderScanner scanner = new FolderScanner(Server.MapPath("/"));
return scanner.scan();
}
}
}
Server.MapPath seems not available from System.Web namespace.
Project is using ASP.NET 5 and dotNET 4.6 Framework
You will need to inject IWebHostEnvironment into your class to have access to the ApplicationBasePath property value: Read about Dependency Injection. After successfully injecting the dependency, the wwwroot path should be available to you. For example:
private readonly IWebHostEnvironment _appEnvironment;
public ProductsController(IWebHostEnvironment appEnvironment)
{
_appEnvironment = appEnvironment;
}
Usage:
[HttpGet]
public IEnumerable<string> Get()
{
FolderScanner scanner = new FolderScanner(_appEnvironment.WebRootPath);
return scanner.scan();
}
Edit: IHostingEnvironment has been replaced by IWebHostEnvironment in later versions of asp.net.
I know this has already been answered, but it has given me different results depending on my hosting environment (IIS Express vs IIS). The following approach seems to work for all hosting environments nicely if you want to get your wwwroot path (see this GitHub issue).
For example
private readonly IHostingEnvironment _hostEnvironment;
public ProductsController(IHostingEnvironment hostEnvironment)
{
_hostEnvironment = hostEnvironment;
}
[HttpGet]
public IEnumerable<string> Get()
{
FolderScanner scanner = new FolderScanner(_hostEnvironment.WebRootPath);
return scanner.scan();
}
For those who deploy to Azure and come into this error. What I did was a work around for it, I haven't tried to figure out why environment of Azure is different than local IIS.
Here is my work around:
if (string.IsNullOrWhiteSpace(_environment.WebRootPath))
{
_environment.WebRootPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
}
Of course you will need:
private IHostingEnvironment _environment;
public OnboardingController(IHostingEnvironment environment)
{
_environment = environment;
}
There is another way to implement this right from startup. It is not exact solution to this case per se, but I modified it to suit my need. We need a singleton for this. This is a startup class with environment injection.
namespace www
{
public class Startup
{
private IHostingEnvironment _env;
public Startup(IHostingEnvironment env)
{
_env = env;
Environment.rootPath = env.WebRootPath;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
app.UseMvc();
}
}
}
The environment variables I was looking for is there, IHOstingEnvironment. But for my purpose, I need to make Environment class like this to easily access all environment items from all project. This singleton will provide data to configuration, environment, and many other thing. But for this thread, I would just put one rootPath property.
namespace www.Utilities
{
public class Environment
{
private static Environment instance;
private static String _rootPath;
private Environment() { }
public static Environment Instance
{
get
{
if (instance == null)
{
instance = new Environment();
}
return instance;
}
}
public static string rootPath
{
set
{
_rootPath = value;
}
get
{
return _rootPath;
}
}
}
}
As I have accepted Oluwafemi's answers, I'll keep it that way, since he led me to this. But I think this is the better way to access environment variables throughout the project