API web de Microsoft: ¿Cómo se hace un Server.MapPath?

239

Como la API web de Microsoft no es MVC , no puede hacer algo como esto:

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

ni esto

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

porque estos están debajo del System.Webespacio de nombres, no el System.Web.Httpespacio de nombres.

Entonces, ¿cómo calcula la ruta relativa del servidor en la API web ?
Solía ​​hacer algo así en MVC :

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

Lo que me daría la ruta absoluta en el disco:

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

Respuestas:

470

Puede usar HostingEnvironment.MapPath en cualquier contexto en el que System.Webobjetos como HttpContext.Currentno estén disponibles (por ejemplo, también desde un método estático).

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

Consulte también ¿Cuál es la diferencia entre Server.MapPath y HostingEnvironment.MapPath?

StuartLC
fuente
1
Esto es bueno, pero no hay una manera fácil de burlarse de HostingEnvironment ya que es una instancia de clase estática ... :-(
Josh G
66
Claro, pero en su controlador u otra capa lógica que desea probar, solo dependería de su propia abstracción, como IPathMapper(probablemente acumule esto con un montón de otras preocupaciones en una interfaz de herramienta / cinturón de herramientas más grande) con el método string MapPath(string virtualPath). Solo la implementación concreta para sus WebApi IPathMappernecesidadesSystem.Web.Hosting.HostingEnvironment
StuartLC
1
@JoshG: puede abstraer HostingEnvironment.MapPath a través de Func <string, string> GetWebPath = HostingEnvironment.MapPath y luego sobrescribir GetWebPath en el momento de la prueba con un simulacro.
Sean B
parece que esto está teniendo problemas con caminos relativos como../images/
AaA
Está dando la ruta del controlador, entonces, ¿puedo obtener la ruta del servicio utilizando el "Ambiente de alojamiento"?
Md Aslam
13
string root = HttpContext.Current.Server.MapPath("~/App_Data");
ArgeKumandan
fuente
16
No desea utilizar HttpContext.Current en WebAPI. ¿Qué pasa con las API autohospedadas? No puede confiar en HttpContext.Current para estar allí. Además, no es una prueba amigable.
Trevor de Koekkoek
2

Además de aquellos que se topan con esto, una buena manera de ejecutar el nivel de prueba al usar la llamada HostingEnvironment es si accediendo, por ejemplo, un recurso compartido UNC: \ example \ que está asignado a ~ / example / podría ejecutar esto para evitarlo Problemas de 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

Me parece útil en caso de que tenga derechos para probar localmente en un archivo, pero necesita la asignación de env una vez en producción.

Nathan Teague
fuente
Fyi, la HostingEnvironmentclase está en el System.Web.Hostingespacio de nombres.
Dermot
2
¿Cuál es la alternativa a HostingEnvironment DNX core 5.0?
roydukkey
La nueva clase Startup.cs ahora inyecta un Startup público (IHostingEnvironment env) {} en la construcción, la propiedad se me olvida, acabo de hacer esto el otro día. eso le permite controlar también un entorno por instancia, y mediante el uso de las directivas #if, cree una aplicación que pueda desplegarse en varios niveles fácilmente en múltiples entornos.
Nathan Teague
1

No puedo decir que desde el contexto en el que la oferta, pero si es algo que sólo tiene que hacer en el inicio de aplicaciones, todavía se puede utilizar Server.MapPathen WebApiHttpApplication; por ejemplo, en Application_Start().

Solo estoy respondiendo tu pregunta directa; la ya mencionada HostingEnvironment.MapPath()es probablemente la solución preferida.

cinta adhesiva
fuente
0

Como Server.MapPath()no existe dentro de una API web (Soap o REST), deberá indicar el directorio local-relativo al contexto de inicio del servidor web. La forma más fácil de hacerlo es con:

string AppContext.BaseDirectory { get;}

Luego puede usar esto para concatenar una cadena de ruta para asignar la ruta relativa a cualquier archivo.
NOTA: las rutas de cadena son \y no /como si estuvieran en mvc.

Ex:

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

devuelve verdadero postulando que esta es una ruta de sonido en su ejemplo

Invitado
fuente
-1

La respuesta seleccionada no funcionó en mi aplicación API web. Tuve que usar

System.Web.HttpRuntime.AppDomainAppPath
Cerca cerca
fuente
1
Aunque parece que esta es la única manera de conseguir ruta a su aplicación WebAPI, esto le da raíz de su aplicación, pero no se traduce rutas relativas como ~\foldero ../images/de rutas físicas
AaA
-1

Puedes probar como:

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

SANDIP G.PATIL
fuente