2008-09-21 11 views
86

Uso un System.Timers.Timer en mi aplicación Asp.Net y necesito usar el método HttpServerUtility.MapPath que parece estar disponible solo en HttpContext.Current.Server.MapPath. El problema es que HttpContext.Current es null cuando se desencadena el evento Timer.Elapsed.¿Cómo acceder al método HttpServerUtility.MapPath en un subproceso o temporizador?

¿Hay alguna otra manera de obtener una referencia a un objeto HttpServerUtility? Podría inyectarlo en el constructor de mi clase. Es seguro ? ¿Cómo puedo estar seguro de que no será un Recolector de Basura al final de la solicitud actual?

Gracias!

Respuesta

138

Es posible utilizar HostingEnvironment.MapPath() en lugar de HttpContext.Current.Server.MapPath()

no he probado todavía en un evento de hilo o temporizador sin embargo.


Algunas soluciones (no viables) que consideré;

  • El único método que me importa es el HttpServerUtilityMapPath. Entonces, como alternativa, podría usar AppDomain.CurrentDomain.BaseDirectory y construir mis rutas a partir de esto. Pero esto fallará si su aplicación usa directorios virtuales (Mine does).

  • Otro enfoque: Agregue todas las rutas que necesito a la clase Global. Resuelva estos caminos en Application_Start.

+1

Sin embargo, tenga en cuenta que lo anterior no funciona en las versiones posteriores de IIS. En IIS7, el inicio de la aplicación se puede invocar fuera de una solicitud http. Es decir, el ejemplo del código. Estoy seguro de que HostingEnvironment.MapPath() seguirá funcionando como lo hacía antes. – Robba

+0

Pero HostingEnvironment.MapPath() da un error si lo pasa y vacía la cadena para obtener la ruta de la carpeta directamente ... HttpContext.Current.Server.MapPath (""); -> funciona HostingEnvironment.MapPath (""); -> plantea el error – VSP

0

Creo que el motivo por el cual es nulo en ese momento (si lo piensas), es que el evento del temporizador transcurrido no ocurre como parte de una solicitud HTTP (por lo tanto, no hay contexto). Es causado por algo en tu servidor.

2

¿No puede llamar a la función MapPath antes de iniciar el temporizador, y simplemente almacenar en caché el resultado? ¿Es absolutamente necesario tener la llamada MapPath dentro del evento tick?

2

Cuando transcurre el tiempo del temporizador, no hay un contexto HTTP actual. Esto se debe a que los eventos del temporizador no están relacionados con una solicitud HTTP específica.

Lo que debe hacer es utilizar HttpServerUtility.MapPath, donde el contexto HTTP está disponible. Puede hacerlo en uno de los eventos de interconexión de solicitudes (como Page_Load) o en un evento Global.asax como Application_Start.

Asigne el resultado de MapPath a una variable accesible desde el evento Timer.Elapsed, donde puede usar Path.Combine para obtener la ubicación de un archivo específico que necesita.

14

No sé si esto va a resolver su problema de directorios virtuales, pero yo lo uso para MapPath:

public static string MapPath(string path) 
{ 
    if (HttpContext.Current != null) 
     return HttpContext.Current.Server.MapPath(path); 

    return HttpRuntime.AppDomainAppPath + path.Replace("~", string.Empty).Replace('/', '\\'); 
} 
+0

ruta.Replace ("~", string.Empty) debe ser path.Replace ('~', '.') – Slava

13

HostingEnvironment no es la solución perfecta porque es una clase muy difícil de burlar (ver How to unit test code that uses HostingEnvironment.MapPath).

Para aquellos que necesitan la capacidad de prueba, de una manera mejor podría ser la de crear su propia interfaz de ruta mapeador según lo propuesto por https://stackoverflow.com/a/1231962/85196, excepto implementarlo como

public class ServerPathMapper : IPathMapper { 
public string MapPath(string relativePath) { 
     return HostingEnvironment.MapPath(relativePath); 
} 
} 

El resultado es fácilmente mockable, utiliza HostingEnvironment internamente, y incluso podría dirigirse a ase69s's concern al mismo tiempo.

+0

Esto me permitió proporcionar una implementación para la resolución de ruta para un proyecto de API web sin requerir una dependencia de System.Web o System.Net en la biblioteca a la que hacía referencia. +1 –

+0

Thumbs up for DI y Testability de este enfoque –

Cuestiones relacionadas