API Web Microsoft: comment faire un Server.MapPath?


239

Étant donné que Microsoft Web API n'est pas MVC , vous ne pouvez pas faire quelque chose comme ceci:

var a = Request.MapPath("~");

ni ça

var b = Server.MapPath("~");

car ceux-ci sont sous l' System.Webespace de noms, pas l' System.Web.Httpespace de noms.

Alors, comment déterminez-vous le chemin d'accès relatif du serveur dans l' API Web ?
J'avais l'habitude de faire quelque chose comme ça dans MVC :

var myFile = Request.MapPath("~/Content/pics/" + filename);

Ce qui me donnerait le chemin absolu sur le disque:

"C:\inetpub\wwwroot\myWebFolder\Content\pics\mypic.jpg"

Réponses:


470

Vous pouvez utiliser HostingEnvironment.MapPath dans n'importe quel contexte où des System.Webobjets comme HttpContext.Currentne sont pas disponibles (par exemple également à partir d'une méthode statique).

var mappedPath = System.Web.Hosting.HostingEnvironment.MapPath("~/SomePath");

Voir également Quelle est la différence entre Server.MapPath et HostingEnvironment.MapPath?


1
C'est bien, mais il n'y a pas de moyen facile de se moquer de HostingEnvironment car c'est une instance de classe statique ... :-(
Josh G

6
Bien sûr, mais dans votre contrôleur ou autre couche logique que vous souhaitez tester, vous ne dépendriez que de votre propre abstraction, comme IPathMapper(vous allez probablement regrouper cela avec un tas d'autres préoccupations dans une plus grande interface de ceinture d'outils / utilitaire) avec la méthode string MapPath(string virtualPath). Seule l'implémentation concrète pour vos WebApi IPathMapperbesoins à savoirSystem.Web.Hosting.HostingEnvironment
StuartLC

1
@JoshG - vous pouvez résumer HostingEnvironment.MapPath via Func <chaîne, chaîne> GetWebPath = HostingEnvironment.MapPath, puis remplacer GetWebPath au moment du test avec une maquette.
Sean B

on dirait que cela a du mal avec des chemins relatifs comme../images/
AaA

Son donnant le chemin du contrôleur, puis-je obtenir le chemin du service en utilisant le "HostingEnvironment"?
Md Aslam

13
string root = HttpContext.Current.Server.MapPath("~/App_Data");

16
Vous ne voulez pas utiliser HttpContext.Current dans WebAPI. Qu'en est-il des API auto-hébergées? Vous ne pouvez pas compter dans HttpContext.Current pour y être. De plus, ce n'est pas un test convivial.
Trevor de Koekkoek

2

En plus de ceux qui trébuchent, une bonne façon d'exécuter le niveau de test sur l'utilisation de l'appel HostingEnvironment est si vous accédez à un partage UNC par exemple: \ example \ qui est mappé sur ~ / example / vous pouvez l'exécuter pour contourner Problèmes avec IIS-Express:

#if DEBUG
    var fs = new FileStream(@"\\example\file",FileMode.Open, FileAccess.Read);
#else
    var fs = new FileStream(HostingEnvironment.MapPath("~/example/file"), FileMode.Open, FileAccess.Read);
#endif

Je trouve cela utile dans le cas où vous avez le droit de tester localement sur un fichier, mais que vous avez besoin du mappage env une fois en production.


Pour info, la HostingEnvironmentclasse est dans l' System.Web.Hostingespace de noms.
Dermot

2
Quelle est l'alternative à HostingEnvironment DNX core 5.0?
roydukkey

La nouvelle classe Startup.cs injecte désormais un démarrage public (IHostingEnvironment env) {} lors de la construction, la propriété me dérange l'esprit, je l'ai fait l'autre jour. qui vous permet également de contrôler un environnement par instance, et en utilisant les directives #if, créez une application qui peut se déployer sur plusieurs niveaux facilement dans plusieurs environnements.
Nathan Teague

1

Je ne peux pas le dire à partir du contexte que vous fournissez, mais si c'est quelque chose que vous devez simplement faire au démarrage de l'application, vous pouvez toujours l'utiliser Server.MapPathdans WebApiHttpApplication; par exemple dansApplication_Start() .

Je réponds simplement à votre question directe; le déjà mentionné HostingEnvironment.MapPath()est probablement la solution préférée.


0

Étant donné qu'il Server.MapPath()n'existe pas dans une API Web (Soap ou REST), vous devrez indiquer le répertoire local par rapport au répertoire home du contexte du serveur Web. La façon la plus simple de le faire est de:

string AppContext.BaseDirectory { get;}

Vous pouvez ensuite l'utiliser pour concaténer une chaîne de chemin d'accès pour mapper le chemin d'accès relatif à n'importe quel fichier.
REMARQUE: les chemins de chaîne sont \et non /comme ils le sont dans mvc.

Ex:

System.IO.File.Exists($"{**AppContext.BaseDirectory**}\\\\Content\\\\pics\\\\{filename}");

renvoie vrai, en posant que c'est un chemin sonore dans votre exemple


-1

La réponse sélectionnée n'a pas fonctionné dans mon application Web API. Je devais utiliser

System.Web.HttpRuntime.AppDomainAppPath

1
Bien qu'il semble que ce soit la seule façon d'obtenir le chemin vers votre application WebApi, cela vous donne la racine de votre application mais ne traduit pas les chemins relatifs tels que ~\folderou ../images/vers les chemins physiques
AaA

-1

Vous pouvez essayer comme:

var path = "~ / Image / test.png"; System.Web.Hosting.HostingEnvironment.MapPath (@ + chemin)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.