My project has a folder structure to the tune of:
In the server (running in the Project/Server folder) I refer to the folder like this:
var rootFolder = Directory.GetCurrentDirectory();
rootFolder = rootFolder.Substring(0,
rootFolder.IndexOf(@"\Project\", StringComparison.Ordinal) + @"\Project\".Length);
PathToData = Path.GetFullPath(Path.Combine(rootFolder, "Data"));
var Parser = Parser();
var d = new FileStream(Path.Combine(PathToData, $"{dataFileName}.txt"), FileMode.Open);
var fs = new StreamReader(d, Encoding.UTF8);
On my windows machine this code works fine since Directory.GetCurrentDirectory()
reffered to the current folder, and doing
rootFolder.Substring(0, rootFolder.IndexOf(@"\Project\", StringComparison.Ordinal) + @"\Project\".Length);
gets me the root folder of the project (not the bin or debug folders).
But when I ran it on a mac it got "Directory.GetCurrentDirectory()
" sent me to /usr//[something else]. It didn't refer to the folder where my project lies.
What is the correct way to find relative paths in my project? Where should I store the data folder in a way that it is easily accessible to all the sub projects in the solution - specifically to the kestrel server project? I prefer to not have to store it in the wwwroot folder because the data folder is maintained by a different member in the team, and I just want to access the latest version. What are my options?
Right-click the Web application you want more information about, such as SharePoint (80), and then click Properties. In the Default Web Site Properties window, click the Home Directory tab. The Local Path field in this tab shows the Web application root folder.
The path of the wwwroot folder is accessed using the interfaces IHostingEnvironment (. Net Core 2.0) and IWebHostEnvironment (. Net Core 3.0) in ASP.Net Core. The IHostingEnvironment is an interface for .
In-process hosting runs an ASP.NET Core app in the same process as its IIS worker process. In-process hosting provides improved performance over out-of-process hosting because requests aren't proxied over the loopback adapter, a network interface that returns outgoing network traffic back to the same machine.
Depending on where you are in the kestrel pipeline - if you have access to IConfiguration
(Startup.cs
constructor) or IWebHostEnvironment
(formerly IHostingEnvironment
) you can either inject the IWebHostEnvironment
into your constructor or just request the key from the configuration.
IWebHostEnvironment
in Startup.cs
Constructorpublic Startup(IConfiguration configuration, IWebHostEnvironment env)
{
var contentRoot = env.ContentRootPath;
}
public Startup(IConfiguration configuration)
{
var contentRoot = configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
}
Working on .Net Core 2.2 and 3.0 as of now.
To get the projects root directory within a Controller:
Create a property for the hosting environment
private readonly IHostingEnvironment _hostingEnvironment;
Add Microsoft.AspNetCore.Hosting to your controller
using Microsoft.AspNetCore.Hosting;
Register the service in the constructor
public HomeController(IHostingEnvironment hostingEnvironment) {
_hostingEnvironment = hostingEnvironment;
}
Now, to get the projects root path
string projectRootPath = _hostingEnvironment.ContentRootPath;
To get the "wwwroot" path, use
_hostingEnvironment.WebRootPath
In some cases _hostingEnvironment.ContentRootPath
and System.IO.Directory.GetCurrentDirectory()
targets to source directory. Here is bug about it.
The solution proposed there helped me
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
As previously answered (and retracted). To get the base directory, as in the location of the running assembly, don't use Directory.GetCurrentDirectory(), rather get it from IHostingEnvironment.ContentRootPath.
private IHostingEnvironment _hostingEnvironment;
private string projectRootFolder;
public Program(IHostingEnvironment env)
{
_hostingEnvironment = env;
projectRootFolder = env.ContentRootPath.Substring(0,
env.ContentRootPath.LastIndexOf(@"\ProjectRoot\", StringComparison.Ordinal) + @"\ProjectRoot\".Length);
}
However I made an additional error: I had set the ContentRoot Directory to Directory.GetCurrentDirectory() at startup undermining the default value which I had so desired! Here I commented out the offending line:
public static void Main(string[] args)
{
var host = new WebHostBuilder().UseKestrel()
// .UseContentRoot(Directory.GetCurrentDirectory()) //<== The mistake
.UseIISIntegration()
.UseStartup<Program>()
.Build();
host.Run();
}
Now it runs correctly - I can now navigate to sub folders of my projects root with:
var pathToData = Path.GetFullPath(Path.Combine(projectRootFolder, "data"));
I realised my mistake by reading BaseDirectory vs. Current Directory and @CodeNotFound founds answer (which was retracted because it didn't work because of the above mistake) which basically can be found here: Getting WebRoot Path and Content Root Path in Asp.net Core
Try looking here: Best way to get application folder path
To quote from there:
System.IO.Directory.GetCurrentDirectory()
returns the current directory, which may or may not be the folder where the application is located. The same goes for Environment.CurrentDirectory. In case you are using this in a DLL file, it will return the path of where the process is running (this is especially true in ASP.NET).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With