Microsoft Web API: Wie wird ein Server.MapPath erstellt?

239

Da die Microsoft Web API keine MVC ist , können Sie Folgendes nicht tun:

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

noch das

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

weil sich diese unter dem System.WebNamespace befinden, nicht unter dem System.Web.HttpNamespace.

Wie ermitteln Sie den relativen Serverpfad in der Web-API ?
Ich habe so etwas in MVC gemacht :

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

Welches würde mir den absoluten Pfad auf der Festplatte geben:

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

Antworten:

469

Sie können HostingEnvironment.MapPath in jedem Kontext verwenden, in dem System.WebObjekte wie HttpContext.Currentnicht verfügbar sind (z. B. auch über eine statische Methode).

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

Siehe auch Was ist der Unterschied zwischen Server.MapPath und HostingEnvironment.MapPath?

StuartLC
quelle
1
Das ist schön, aber es gibt keine einfache Möglichkeit, HostingEnvironment zu verspotten, da es sich um eine statische Klasseninstanz handelt ... :-(
Josh G
6
Sicher, aber in Ihrem Controller oder einer anderen Logikschicht, die Sie testen möchten, würden Sie nur eine Abhängigkeit von Ihrer eigenen Abstraktion annehmen, wie IPathMapper(Sie werden dies wahrscheinlich mit einer Reihe anderer Bedenken in eine größere Toolbelt / Utility-Oberfläche zusammenfassen). mit der Methode string MapPath(string virtualPath). Nur die konkrete Implementierung für Ihre WebApi IPathMapperBedürfnisse muss bekannt seinSystem.Web.Hosting.HostingEnvironment
StuartLC
1
@JoshG - Sie können HostingEnvironment.MapPath über Func <string, string> GetWebPath = HostingEnvironment.MapPath abstrahieren und GetWebPath zur Testzeit mit einem Mock überschreiben.
Sean B
sieht so aus, als hätte dies Probleme mit relativen Pfaden wie../images/
AaA
Gibt es den Controller-Pfad an? Kann ich den Service-Pfad mithilfe der "HostingEnvironment" abrufen?
Md Aslam
13
string root = HttpContext.Current.Server.MapPath("~/App_Data");
ArgeKumandan
quelle
16
Sie möchten HttpContext.Current nicht in WebAPI verwenden. Was ist mit selbst gehosteten APIs? Sie können sich nicht darauf verlassen, dass HttpContext.Current dort ist. Auch ist es nicht testfreundlich.
Trevor de Koekkoek
2

Abgesehen von denjenigen, die darüber stolpern, besteht eine gute Möglichkeit, die Testebene bei Verwendung des HostingEnvironment-Aufrufs auszuführen, darin, beispielsweise auf eine UNC-Freigabe zuzugreifen: \ example \, die ~ / example / zugeordnet ist. Sie können dies ausführen, um herumzukommen IIS-Express-Probleme:

#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

Ich finde das hilfreich, wenn Sie Rechte zum lokalen Testen einer Datei haben, aber die env-Zuordnung einmal in der Produktion benötigen.

Nathan Teague
quelle
Zu Ihrer Information, die HostingEnvironmentKlasse befindet sich im System.Web.HostingNamespace.
Dermot
2
Was ist die Alternative zu HostingEnvironment DNX Core 5.0?
Roydukkey
Die neue Startup.cs-Klasse injiziert jetzt ein öffentliches Startup (IHostingEnvironment env) {} beim Erstellen. Die Eigenschaft ist mir ein Rätsel. Ich habe dies neulich getan. Auf diese Weise können Sie auch eine Umgebung pro Instanz steuern und mithilfe von # if-Anweisungen eine App erstellen, die die Bereitstellung in mehreren Umgebungen problemlos über mehrere Ebenen hinweg ermöglichen kann.
Nathan Teague
1

Ich kann nicht aus dem Zusammenhang sagen Sie liefern, aber wenn es etwas , das Sie nur bei App Startup tun müssen, können Sie verwenden , Server.MapPathin WebApiHttpApplication; zB in Application_Start().

Ich beantworte nur Ihre direkte Frage. Das bereits erwähnte HostingEnvironment.MapPath()ist wahrscheinlich die bevorzugte Lösung.

Klebeband
quelle
0

Da Server.MapPath()es in einer Web-API (Soap oder REST) ​​nicht vorhanden ist, müssen Sie das lokale Verhältnis zum Kontext-Home-Verzeichnis des Webservers angeben. Der einfachste Weg, dies zu tun, ist mit:

string AppContext.BaseDirectory { get;}

Sie können dies dann verwenden, um eine Pfadzeichenfolge zu verketten und den relativen Pfad einer beliebigen Datei zuzuordnen.
HINWEIS: Zeichenfolgenpfade sind \und nicht /wie in MVC.

Ex:

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

gibt true zurück und setzt voraus, dass dies in Ihrem Beispiel ein Soundpfad ist

Gast
quelle
-1

Die ausgewählte Antwort funktionierte in meiner Web-API-Anwendung nicht. Ich musste benutzen

System.Web.HttpRuntime.AppDomainAppPath
Zoomzoom
quelle
1
Obwohl dies anscheinend die einzige Möglichkeit ist, einen Pfad zu Ihrer WebApi-App zu erhalten, erhalten Sie den Stamm Ihrer Anwendung, können jedoch keine relativen Pfade wie ~\folderoder ../images/in physische Pfade übersetzen
AaA
-1

Sie können versuchen wie:

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

SANDIP G.PATIL
quelle