martes, 3 de octubre de 2017
Al dar el salto a una nueva tecnología como ASP.NET Core, en muchas ocasiones nos encontramos con el problema de no saber cómo hacer cosas que con las tecnologías tradicionales teníamos completamente controladas. Ya hemos comentado por aquí varios casos (como el Application_Start(), los custom errors o las variables de sesión) y hemos visto cómo se mapean estas funciones al nuevo framework, pero hay muchos más.
Otro ejemplo muy habitual lo encontramos con
La solución más sencilla es utilizar el sistema de inyección de dependencias para obtener una instancia de
Publicado en Variable not found.
Otro ejemplo muy habitual lo encontramos con
MapPath()
, un método perteneciente a la clase HttpServerUtility
de ASP.NET "clásico" que utilizábamos para obtener una ruta física a partir de la ruta virtual o relativa de un recurso. Por ejemplo, en el siguiente código mostramos cómo averiguar la ruta en disco de una imagen utilizando este método:var path = HttpContext.Current.Server.MapPath("~/images/image.jpg"); // path = C:\inetpub\wwwroot\mysite\images\image.jpgPues bien, ni en ASP.NET Core ni en MVC tenemos disponible la clase
System.Web.HttpContext
, ni por tanto una propiedad Server
de tipo HttpServerUtility
que usábamos para invocar al método MapPath()
. Sin embargo, disponemos de herramientas alternativas que nos permiten conseguir lo mismo, aunque, eso sí, de forma algo menos directa.La solución más sencilla es utilizar el sistema de inyección de dependencias para obtener una instancia de
IHostingEnvironment
, a través de la cual podremos obtener el directorio raíz físico del sitio web o, si lo deseamos, de la carpeta configurada como "wwwroot" del mismo. Tras ello, sólo tenemos que componer la ruta final usando métodos clásicos como System.IO.Path.Combine()
. En un controlador MVC podría ser algo así:public class TestController : Controller { private readonly IHostingEnvironment _env; public TestController(IHostingEnvironment env) { _env = env; } public IActionResult Index() { var path = Path.Combine(_env.WebRootPath, "images", "image.jpg"); // path = C:\inetpub\wwwroot\mysite\wwwroot\images\image.jpg ... } }En cambio, si queremos tomar como punto de partida el directorio raíz de la aplicación, que normalmente estará un nivel por arriba de "wwwroot", simplemente debemos usar la propiedad
ContentRootPath
:var path = Path.Combine(_env.ContentRootPath, "images", "image.jpg"); // path = C:\inetpub\wwwroot\mysite\images\image.jpgObservad que al usar
Combine()
y no concatenaciones o rutas hard-coded, conseguimos que el resultado sea sensible al sistema operativo, por ejemplo en cuanto a los caracteres separadores de carpetas.Publicado en Variable not found.
4 Comentarios:
Hola! En el segundo ejemplo creo que el copia pega te ha traicionado, ya que no hay referencia a ContentRootPath.
Aprovecho para dar las gracias por todo tu trabajo, que me ayuda mucho.
Aaarrgg!! Tienes razón, maldito copiapega! ;D
Está solucionado, muchas gracias por avisar y por tus comentarios.
Saludos!
El asunto es cuando es necesario pasar otras interfaces en el constructor como IOptions o IHttpContextAccessor, el constructor del controller se pone tonto..
Hola!
Pues no debería, son interfaces bastante habituales... ¿qué te ocurre exactamente?
Saludos!
Enviar un nuevo comentario