[英]In ASP.NET MVC 5 Server.MapPath() returning path with double backslashes
[英]How to get absolute path in ASP.Net Core alternative way for Server.MapPath
如何在ASP net core中获取Server.MapPath
绝对路径替代方式
我曾尝试使用IHostingEnvironment
但它没有给出正确的结果。
IHostingEnvironment env = new HostingEnvironment();
var str1 = env.ContentRootPath; // Null
var str2 = env.WebRootPath; // Null, both doesn't give any result
我在wwwroot文件夹中有一个图像文件 (Sample.PNG) 我需要获取此绝对路径。
从 .Net Core v3.0 开始,访问WebRootPath
应该是IWebHostEnvironment
,该WebRootPath
已移至 Web 特定环境界面。
将IWebHostEnvironment
作为依赖项注入依赖类。 该框架将为您填充它
public class HomeController : Controller {
private IWebHostEnvironment _hostEnvironment;
public HomeController(IWebHostEnvironment environment) {
_hostEnvironment = environment;
}
[HttpGet]
public IActionResult Get() {
string path = Path.Combine(_hostEnvironment.WebRootPath, "Sample.PNG");
return View();
}
}
您可以更进一步,创建自己的路径提供程序服务抽象和实现。
public interface IPathProvider {
string MapPath(string path);
}
public class PathProvider : IPathProvider {
private IWebHostEnvironment _hostEnvironment;
public PathProvider(IWebHostEnvironment environment) {
_hostEnvironment = environment;
}
public string MapPath(string path) {
string filePath = Path.Combine(_hostEnvironment.WebRootPath, path);
return filePath;
}
}
并将IPathProvider
注入依赖类。
public class HomeController : Controller {
private IPathProvider pathProvider;
public HomeController(IPathProvider pathProvider) {
this.pathProvider = pathProvider;
}
[HttpGet]
public IActionResult Get() {
string path = pathProvider.MapPath("Sample.PNG");
return View();
}
}
确保将服务注册到 DI 容器
services.AddSingleton<IPathProvider, PathProvider>();
* Hack *不推荐,但仅供参考,您可以使用var abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\\\","");
从相对路径获取绝对路径var abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\\\","");
更喜欢上面的 DI/Service 方法,但如果您处于非 DI 情况(例如,使用Activator
实例化的类),这将起作用。
变量 1:
string path = System.IO.Directory.GetCurrentDirectory();
变量 2:
string path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, AppDomain.CurrentDomain.BaseDirectory.IndexOf("\\bin"));
例如我想定位~/wwwroot/CSS
public class YourController : Controller
{
private readonly IWebHostEnvironment _webHostEnvironment;
public YourController (IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment= webHostEnvironment;
}
public IActionResult Index()
{
string webRootPath = _webHostEnvironment.WebRootPath;
string contentRootPath = _webHostEnvironment.ContentRootPath;
string path ="";
path = Path.Combine(webRootPath , "CSS");
//or path = Path.Combine(contentRootPath , "wwwroot" ,"CSS" );
return View();
}
}
此外,如果您没有控制器或服务,请按照最后一部分并将其注册为单例。 然后,在 Startup.ConfigureServices 中:
services.AddSingleton<your_class_Name>();
最后,在需要的地方注入your_class_Name
。
例如我想定位~/wwwroot/CSS
public class YourController : Controller
{
private readonly IHostingEnvironment _HostEnvironment;
public YourController (IHostingEnvironment HostEnvironment)
{
_HostEnvironment= HostEnvironment;
}
public ActionResult Index()
{
string webRootPath = _HostEnvironment.WebRootPath;
string contentRootPath = _HostEnvironment.ContentRootPath;
string path ="";
path = Path.Combine(webRootPath , "CSS");
//or path = Path.Combine(contentRootPath , "wwwroot" ,"CSS" );
return View();
}
}
感谢@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
。
更好的解决方案是使用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);
}
正如你所看到的,这个逻辑(文件来自哪里)可能会变得非常复杂,但如果它发生变化,你的代码不会中断。
如果您有一些特殊的逻辑,您可以使用new PhysicalFileProvider(root)
创建自定义IFileProvider
。 我有一种情况,我想在中间件中加载图像,然后调整大小或裁剪它。 但它是一个 Angular 项目,因此部署的应用程序的路径不同。 我编写的中间件从startup.cs
获取IFileProvider
,然后我可以像过去使用MapPath
一样使用GetFileInfo()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.