Comment accéder à la méthode HttpServerUtility.MapPath dans un thread ou une minuterie?

StackOverflow https://stackoverflow.com/questions/111927

Question

J'utilise un System.Timers.Timer dans mon application Asp.Net et je dois utiliser la méthode HttpServerUtility.MapPath qui semble uniquement disponible via HttpContext.Current.Server.MapPath . Le problème est que HttpContext.Current est null lorsque l'événement Timer.Elapsed est déclenché.

Existe-t-il un autre moyen d'obtenir une référence à un objet HttpServerUtility? Je pourrais l'injecter dans le constructeur de ma classe. Est-ce sûr ? Comment puis-je être sûr que les ordures ne seront pas récupérées à la fin de la demande en cours?

Merci!

Était-ce utile?

La solution

Il est possible d'utiliser HostingEnvironment.MapPath () au lieu de HttpContext.Current.Server.MapPath ()

Je ne l'ai pas encore essayé dans un événement thread ou timer.

Certaines solutions (non viables) que j'ai envisagées;

  • La seule méthode qui me tient à coeur sur HttpServerUtility est MapPath . Donc, comme alternative, je pourrais utiliser AppDomain.CurrentDomain.BaseDirectory et construire mes chemins à partir de cela. Mais cela échouera si votre application utilise des répertoires virtuels (le mien le fait).

  • Une autre approche: Ajoutez tous les chemins nécessaires à la classe Global . Résolvez ces chemins dans Application_Start .

Autres conseils

Je ne sais pas si cela résoudra le problème de vos répertoires virtuels, mais je l'utilise pour 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 n'est pas la solution idéale, car il est très difficile de se moquer de cette classe (voir Comment unifier le code de test utilisant HostingEnvironment.MapPath ).

Pour ceux qui ont besoin de testabilité, un meilleur moyen pourrait être de créer votre propre interface path-mapper, comme le propose https: // stackoverflow .com / a / 1231962/85196 , à l'exception de l'implémenter comme

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

Le résultat est facilement modulable, utilise HostingEnvironment en interne et pourrait même potentiellement résoudre le problème La préoccupation de ase69s en même temps.

Ne pouvez-vous pas appeler la fonction MapPath avant de démarrer le chronomètre et mettre simplement en cache le résultat? Est-il absolument nécessaire d’avoir l’appel de MapPath dans l’événement tick?

Lorsque le délai est écoulé, il n'y a pas de contexte HTTP actuel. En effet, les événements du minuteur ne sont pas liés à une requête HTTP spécifique.

Ce que vous devriez faire est d’utiliser HttpServerUtility.MapPath où le contexte HTTP est disponible. Vous pouvez le faire dans l'un des événements de pipeline de demandes (tels que Page_Load) ou dans un événement Global.asax tel que Application_Start.

Attribuez le résultat MapPath à une variable accessible à partir de l'événement Timer.Elapsed, où vous pouvez utiliser Path.Combine pour obtenir l'emplacement d'un fichier spécifique dont vous avez besoin.

Je pense que la raison pour laquelle il est nul à ce moment-là (si vous y réfléchissez) est que l'événement minuteur écoulé ne se produit pas dans le cadre d'une requête HTTP (il n'y a donc pas de contexte). Cela est causé par quelque chose sur votre serveur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top