wake-up-neo.com

So erhalten Sie den absoluten Pfad in ASP.Net Core auf alternative Weise für Server.MapPath

Wie erhalte ich den absoluten Pfad in ASP net core alternativer Weise für Server.MapPath

Ich habe versucht, IHostingEnvironment zu verwenden, aber es gibt kein richtiges Ergebnis.

IHostingEnvironment env = new HostingEnvironment();
var str1 = env.ContentRootPath; // Null
var str2 = env.WebRootPath; // Null, both doesn't give any result 

Ich habe eine Bilddatei (Sample.PNG) im Ordner wwwroot , um diesen absoluten Pfad zu erhalten.

26
Shanmu_92

Injizieren Sie IHostingEnvironment als Abhängigkeit in die abhängige Klasse. Das Framework wird es für Sie auffüllen

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

Sie können noch einen Schritt weiter gehen und Ihre eigene Abstraktion und Implementierung von Pfadanbieter-Services erstellen.

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;
    }
}

Und injiziere IPathProvider in abhängige Klassen.

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

Stellen Sie sicher, dass der Dienst im DI-Container registriert ist

services.AddSingleton<IPathProvider, PathProvider>();
74
Nkosi

* Hack * Nicht empfohlen, aber zu Ihrer Information: Mit var abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\",""); können Sie einen absoluten Pfad aus einem relativen Pfad abrufen.

Bevorzugen Sie die obigen DI/Service-Ansätze, aber wenn Sie sich in einer Nicht-DI-Situation befinden (z. B. eine mit Activator instanziierte Klasse), funktioniert dies.

5
Randy Buchholz

Eine bessere Lösung ist die Verwendung der IFileProvider.GetFileInfo() -Methode.

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

Sie müssen IFileProviderso registrieren, um über DI darauf zugreifen zu können:

    // 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);
    }

Wie Sie sehen, kann diese Logik (woher eine Datei stammt) recht komplex werden, aber Ihr Code wird nicht beschädigt, wenn er sich ändert.

Sie können mit new PhysicalFileProvider(root) ein benutzerdefiniertes IFileProvider erstellen, wenn Sie eine spezielle Logik haben. Ich wollte ein Image in die Middleware laden und seine Größe ändern oder es zuschneiden. Da es sich jedoch um ein Angular) - Projekt handelt, ist der Pfad für eine bereitgestellte App anders. Die von mir geschriebene Middleware nimmt IFileProvider von startup.cs Und kann dann einfach GetFileInfo() als hätte ich MapPath in der Vergangenheit benutzt.

3
Simon_Weaver

Dank @NKosi ist aber IHostingEnvironment in MVC Core 3 veraltet !!

gemäß this :

Veraltete Typen (Warnung):

Microsoft.Extensions.Hosting.IHostingEnvironment
Microsoft.AspNetCore.Hosting.IHostingEnvironment
Microsoft.Extensions.Hosting.IApplicationLifetime
Microsoft.AspNetCore.Hosting.IApplicationLifetime
Microsoft.Extensions.Hosting.EnvironmentName
Microsoft.AspNetCore.Hosting.EnvironmentName

Neue Typen:

Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
Microsoft.Extensions.Hosting.IHostApplicationLifetime
Microsoft.Extensions.Hosting.Environments 

Sie müssen also IWebHostEnvironment anstelle von IHostingEnvironment verwenden.

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);
    }
}
2
amir133