簡體   English   中英

如何在 ASP.Net Core 中為 Server.MapPath 獲取絕對路徑替代方法

[英]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實例化的類),這將起作用。

.NET 核心 3.0

變量 1:

string path = System.IO.Directory.GetCurrentDirectory();

變量 2:

string path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, AppDomain.CurrentDomain.BaseDirectory.IndexOf("\\bin"));

.Net 核心 3

例如我想定位~/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


.Net 核心 2

例如我想定位~/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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM