首页 文章

如何在ASP.Net Core中为Server.MapPath获取绝对路径

提问于
浏览
18

如何获得ASP网核替代方式的绝对路径 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)我需要获取这个绝对路径 .

3 回答

  • 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();
        }
    }
    

    确保使用容器注册服务

    services.AddSingleton<IPathProvider, PathProvider>();
    
  • 52

    更好的解决方案是使用 IFileProvider.GetFileInfo() 方法 .

    public IActionResult ResizeCat([FromServices] IFileProvider fileProvider)
        {
            // get absolute path (equivalent to MapPath)
            string absolutePath = fileProvider.GetFileInfo("/assets/images/cat.jpg").PhysicalPath;  
            ... 
        }
    

    你必须注册 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);
        }
    

    正如您所看到的那样,逻辑(文件来自哪里)可能变得非常复杂,但如果更改,您的代码将不会中断 .

    如果您有一些特殊逻辑,可以使用 new PhysicalFileProvider(root) 创建自定义 IFileProvider . 我有一种情况,我想在中间件中加载图像,并调整大小或裁剪它 . 但它是一个Angular项目,因此部署的应用程序的路径不同 . 我编写的中间件从 startup.cs 获取 IFileProvider 然后我可以使用 GetFileInfo() ,就像我过去使用 MapPath 一样 .

  • 0

    *** Hack *** 不推荐,但是你可以通过 var abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\",""); 获得相对路径的绝对路径

    更喜欢上面的DI /服务方法,但如果您处于非DI情况(例如,用 Activator 实例化的类),这将起作用 .

相关问题