Как получить абсолютный путь в альтернативном Server.MapPath
ASP для Server.MapPath
Я попытался использовать IHostingEnvironment
но он не дает правильного результата.
IHostingEnvironment env = new HostingEnvironment();
var str1 = env.ContentRootPath; // Null
var str2 = env.WebRootPath; // Null, both doesn't give any result
У меня есть один файл изображения (Sample.PNG) в папке wwwroot. Мне нужно получить этот абсолютный путь.
Ответ 1
IHostingEnvironment
в качестве зависимости в зависимый класс. Фреймворк заполнит его для вас
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();
}
}
Вы можете пойти еще дальше и создать свою собственную абстракцию и реализацию службы провайдера пути.
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;
}
}
И внедрить IPathProvider
в зависимые классы.
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();
}
}
Обязательно зарегистрируйте службу в контейнере DI
services.AddSingleton<IPathProvider, PathProvider>();
Ответ 2
* Hack * Не рекомендуется, но к вашему сведению вы можете получить абсолютный путь из относительного пути с помощью var abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\","");
Предпочитаю подходы DI/Service выше, но если вы находитесь в ситуации, не связанной с DI (например, класс, созданный с помощью Activator
), это будет работать.
Ответ 3
Лучшим решением является использование IFileProvider.GetFileInfo()
.
public IActionResult ResizeCat([FromServices] IFileProvider fileProvider)
{
// get absolute path (equivalent to MapPath)
string absolutePath = fileProvider.GetFileInfo("/assets/images/cat.jpg").PhysicalPath;
...
}
Вы должны зарегистрировать IFileProvider
как это, чтобы иметь доступ к нему через 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);
}
Как вы можете видеть, эта логика (для чего происходит файл) может стать довольно сложной, но ваш код не сломается, если он изменится.
Вы можете создать пользовательский IFileProvider
с new PhysicalFileProvider(root)
IFileProvider
new PhysicalFileProvider(root)
если у вас есть специальная логика. У меня была ситуация, когда я хочу загрузить изображение в промежуточное программное обеспечение, изменить его размер или обрезать. Но это проект Angular, поэтому для развёрнутого приложения этот путь отличается. IFileProvider
программное обеспечение, которое я написал, берет IFileProvider
из startup.cs
и тогда я мог бы просто использовать GetFileInfo()
как я бы использовал MapPath
в прошлом.
Ответ 4
Благодаря @NKosi, но IHostingEnvironment
устарел в ядре MVC 3 !!
в соответствии с этим:
Устаревшие типы (предупреждение):
Microsoft.Extensions.Hosting.IHostingEnvironment
Microsoft.AspNetCore.Hosting.IHostingEnvironment
Microsoft.Extensions.Hosting.IApplicationLifetime
Microsoft.AspNetCore.Hosting.IApplicationLifetime
Microsoft.Extensions.Hosting.EnvironmentName
Microsoft.AspNetCore.Hosting.EnvironmentName
Новые типы:
Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
Microsoft.Extensions.Hosting.IHostApplicationLifetime
Microsoft.Extensions.Hosting.Environments
Поэтому вы должны использовать IWebHostEnvironment
вместо 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
Вариант 1:
string path = System.IO.Directory.GetCurrentDirectory();
Вар 2:
string path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, AppDomain.CurrentDomain.BaseDirectory.IndexOf("\\bin"));