Pregunta

Uso un System.Timers.Timer en mi aplicación Asp.Net y necesito usar el HttpServerUtility.MapPath método que parece estar sólo disponible a través de HttpContext.Current.Server.MapPath.El problema es ese HttpContext.Current es null cuando el Timer.Elapsed incendios de eventos.

¿Existe otra forma 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 se recolectará basura al final de la solicitud actual?

¡Gracias!

¿Fue útil?

Solución

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

Sin embargo, todavía no lo he probado en un hilo o evento de temporizador.


Algunas soluciones (no viables) que consideré;

  • El único método que me importa HttpServerUtility es MapPath.Entonces, como alternativa, podría usar AppDomain.CurrentDomain.BaseDirectory y construir a partir de esto mis caminos. Pero esto fallará si tu aplicación usa directorios virtuales. (El mío sí).

  • Otro enfoque:Agregue todas las rutas que necesito al Global clase.Resolver estos caminos en Application_Start.

Otros consejos

No sé si esto solucionará el problema de los directorios virtuales, pero yo uso esto 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('/', '\\');
}

HostingEnvironment no es la solución perfecta porque es una clase muy difícil de burlar (ver Cómo realizar una prueba unitaria de código que utiliza HostingEnvironment.MapPath).

Para aquellos que necesitan capacidad de prueba, una mejor manera podría ser crear su propia interfaz de mapeador de ruta como lo propone 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 burlable, utiliza HostingEnvironment internamente e incluso podría abordar La preocupación de ase69s al mismo tiempo.

¿No puedes 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?

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

Lo que debes hacer es usar HttpServerUtility.MapPath donde el contexto HTTP está disponible.Puede hacerlo en uno de los eventos de canalizació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 podría usar Path.Combine para obtener la ubicación de un archivo específico que necesita.

Creo que la razón por la que es nulo en ese momento (si lo piensas bien) es que el evento transcurrido del temporizador no ocurre como parte de una solicitud HTTP (por lo tanto, no hay contexto).Es causado por algo en su servidor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top