Comment obtenir un chemin absolu dans ASP autre moyen de base du réseau pour Server.MapPath
J'ai essayé d'utiliser IHostingEnvironment
mais cela ne donne pas un résultat correct.
IHostingEnvironment env = new HostingEnvironment();
var str1 = env.ContentRootPath; // Null
var str2 = env.WebRootPath; // Null, both doesn't give any result
J'ai un fichier image (Sample.PNG) dans le dossier wwwroot Je dois obtenir ce chemin d'accès absolu.
Injectez IHostingEnvironment
comme dépendance dans la classe dépendante. Le cadre le peuplera pour vous
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();
}
}
Vous pouvez aller plus loin et créer votre propre abstraction et implémentation de services de fournisseur de chemin d'accès.
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;
}
}
Et injectez IPathProvider
dans les classes dépendantes.
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();
}
}
Assurez-vous d'enregistrer le service avec le conteneur DI
services.AddSingleton<IPathProvider, PathProvider>();
* Hack * Non recommandé, mais pour votre information, vous pouvez obtenir un chemin absolu à partir d'un chemin relatif avec var abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\","");
Préférez les approches DI/Service ci-dessus, mais si vous vous trouvez dans une situation autre que DI (par exemple, une classe instanciée avec Activator
), cela fonctionnera.
Une meilleure solution consiste à utiliser la méthode IFileProvider.GetFileInfo()
.
public IActionResult ResizeCat([FromServices] IFileProvider fileProvider)
{
// get absolute path (equivalent to MapPath)
string absolutePath = fileProvider.GetFileInfo("/assets/images/cat.jpg").PhysicalPath;
...
}
Vous devez vous enregistrer IFileProvider
comme ceci pour pouvoir y accéder via 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);
}
Comme vous pouvez le constater, cette logique (d'où provient un fichier) peut devenir assez complexe, mais votre code ne sera pas cassé s'il change.
Vous pouvez créer un IFileProvider
personnalisé avec new PhysicalFileProvider(root)
si vous avez une logique particulière. Je souhaitais charger une image dans un middleware et la redimensionner ou la rogner. Mais il s’agit d’un projet Angular), de sorte que le chemin est différent pour une application déployée. Le middleware que j’ai écrit prend IFileProvider
à partir de startup.cs
, Puis je pourrais simplement utiliser GetFileInfo()
comme j'aurais utilisé MapPath
dans le passé.
Merci à @NKosi mais IHostingEnvironment
est obsolète dans le noyau 3 de MVC !!
selon this :
Types obsolètes (avertissement):
Microsoft.Extensions.Hosting.IHostingEnvironment
Microsoft.AspNetCore.Hosting.IHostingEnvironment
Microsoft.Extensions.Hosting.IApplicationLifetime
Microsoft.AspNetCore.Hosting.IApplicationLifetime
Microsoft.Extensions.Hosting.EnvironmentName
Microsoft.AspNetCore.Hosting.EnvironmentName
Nouveaux types:
Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
Microsoft.Extensions.Hosting.IHostApplicationLifetime
Microsoft.Extensions.Hosting.Environments
Vous devez donc utiliser IWebHostEnvironment
au lieu de 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);
}
}