问题
How to get absolute path in ASP net core alternative way for Server.MapPath
I have tried to use IHostingEnvironment
but it doesn't give proper result.
IHostingEnvironment env = new HostingEnvironment();
var str1 = env.ContentRootPath; // Null
var str2 = env.WebRootPath; // Null, both doesn't give any result
I have one image file (Sample.PNG) in wwwroot folder I need to get this absolute path.
回答1:
Inject IHostingEnvironment
as a dependency into the dependent class. The framework will populate it for you
public class HomeController : Controller {
private IHostingEnvironment _hostingEnvironment;
public HomeController(IHostingEnvironment environment) {
_hostingEnvironment = environment;
}
[HttpGet]
public IActionResult Get() {
var path = Path.Combine(_hostingEnvironment.WebRootPath, "Sample.PNG");
return View();
}
}
You could go one step further and create your own path provider service abstraction and implementation.
public interface IPathProvider {
string MapPath(string path);
}
public class PathProvider : IPathProvider {
private IHostingEnvironment _hostingEnvironment;
public PathProvider(IHostingEnvironment environment) {
_hostingEnvironment = environment;
}
public string MapPath(string path) {
var filePath = Path.Combine(_hostingEnvironment.WebRootPath, path);
return filePath;
}
}
And inject IPathProvider
into dependent classes.
public class HomeController : Controller {
private IPathProvider pathProvider;
public HomeController(IPathProvider pathProvider) {
this.pathProvider = pathProvider;
}
[HttpGet]
public IActionResult Get() {
var path = pathProvider.MapPath("Sample.PNG");
return View();
}
}
Make sure to register the service with the DI container
services.AddSingleton<IPathProvider, PathProvider>();
回答2:
* Hack *
Not recommended, but FYI you can get an absolute path from a relative path with
var abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\","");
Prefer the DI/Service approaches above, but if you are in a non-DI situation (e.g., a class instantiated with Activator
) this will work.
回答3:
A better solution is to use the IFileProvider.GetFileInfo()
method.
public IActionResult ResizeCat([FromServices] IFileProvider fileProvider)
{
// get absolute path (equivalent to MapPath)
string absolutePath = fileProvider.GetFileInfo("/assets/images/cat.jpg").PhysicalPath;
...
}
You must register IFileProvider
like this to be able to access it through DI:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
var physicalProvider = _hostingEnvironment.ContentRootFileProvider;
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
var compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);
// choose one provider to use for the app and register it
//services.AddSingleton<IFileProvider>(physicalProvider);
//services.AddSingleton<IFileProvider>(embeddedProvider);
services.AddSingleton<IFileProvider>(compositeProvider);
}
As you can see this logic (for where a file comes from) can get quite complex, but your code won't break if it changes.
You can create a custom IFileProvider
with new PhysicalFileProvider(root)
if you have some special logic. I had a situation where I want to load an image in middleware, and resize or crop it. But it's an Angular project so the path is different for a deployed app. The middleware I wrote takes IFileProvider
from startup.cs
and then I could just use GetFileInfo()
like I would have used MapPath
in the past.
回答4:
Thanks to @NKosi but IHostingEnvironment
is obsoleted in MVC core 3!!
according to this :
Obsolete types (warning):
Microsoft.Extensions.Hosting.IHostingEnvironment
Microsoft.AspNetCore.Hosting.IHostingEnvironment
Microsoft.Extensions.Hosting.IApplicationLifetime
Microsoft.AspNetCore.Hosting.IApplicationLifetime
Microsoft.Extensions.Hosting.EnvironmentName
Microsoft.AspNetCore.Hosting.EnvironmentName
New types:
Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
Microsoft.Extensions.Hosting.IHostApplicationLifetime
Microsoft.Extensions.Hosting.Environments
So you must use IWebHostEnvironment
instead of IHostingEnvironment
.
public class HomeController : Controller
{
private readonly IWebHostEnvironment _webHostEnvironment;
public HomeController(IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment= webHostEnvironment;
}
public IActionResult Index()
{
string webRootPath = _webHostEnvironment.WebRootPath;
string contentRootPath = _webHostEnvironment.ContentRootPath;
return Content(webRootPath + "\n" + contentRootPath);
}
}
回答5:
.NET Core 3.0
Var 1:
string path = System.IO.Directory.GetCurrentDirectory();
Var 2:
string path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, AppDomain.CurrentDomain.BaseDirectory.IndexOf("\\bin"));
来源:https://stackoverflow.com/questions/43992261/how-to-get-absolute-path-in-asp-net-core-alternative-way-for-server-mappath