Używam System.Timers.Timer
w mojej aplikacji Asp.Net i muszę użyć HttpServerUtility.MapPath
metody, która wydaje się być dostępna tylko za pośrednictwem HttpContext.Current.Server.MapPath
. Problem polega na tym , że zdarzenie HttpContext.Current
to się null
pojawia Timer.Elapsed
.
Czy istnieje inny sposób uzyskania odwołania do obiektu HttpServerUtility? Mógłbym wstrzyknąć go do konstruktora mojej klasy. Czy to jest bezpieczne? Jak mogę się upewnić, że na koniec bieżącego żądania nie zostanie on usunięty?
Dzięki!
źródło
Nie wiem, czy to rozwiąże problem z katalogami wirtualnymi, ale używam tego dla 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('/', '\\'); }
źródło
HostingEnvironment nie jest idealnym rozwiązaniem, ponieważ jest to bardzo trudna klasa do makietowania (zobacz Jak przeprowadzić test jednostkowy kodu, który używa HostingEnvironment.MapPath ).
Dla tych, którzy potrzebują testowalności, lepszym sposobem może być utworzenie własnego interfejsu mapowania ścieżek zgodnie z propozycją https://stackoverflow.com/a/1231962/85196 , z wyjątkiem implementacji jako
public class ServerPathMapper : IPathMapper { public string MapPath(string relativePath) { return HostingEnvironment.MapPath(relativePath); } }
Wynik jest łatwy do podrobienia, wykorzystuje HostingEnvironment wewnętrznie i może nawet potencjalnie rozwiązać problem ase69s w tym samym czasie.
źródło
Czy nie możesz wywołać funkcji MapPath przed uruchomieniem licznika czasu i po prostu zapisać wynik w pamięci podręcznej? Czy jest absolutnie konieczne, aby wywołanie MapPath było wewnątrz zdarzenia tick?
źródło
Po upływie odliczania czasu nie ma bieżącego kontekstu HTTP. Dzieje się tak, ponieważ zdarzenia licznika czasu nie są związane z określonym żądaniem HTTP.
Powinieneś użyć HttpServerUtility.MapPath tam, gdzie jest dostępny kontekst HTTP. Możesz to zrobić w jednym ze zdarzeń potoku żądań (na przykład Page_Load) lub w zdarzeniu Global.asax, takim jak Application_Start.
Przypisz wynik MapPath do zmiennej dostępnej ze zdarzenia Timer.Elapsed, w którym możesz użyć Path.Combine, aby uzyskać lokalizację konkretnego pliku, którego potrzebujesz.
źródło
Myślę, że powodem, dla którego w tym momencie jest zerowa (jeśli się nad tym zastanowić), jest to, że zdarzenie, które upłynęło, nie występuje jako część żądania HTTP (stąd nie ma kontekstu). Jest to spowodowane przez coś na twoim serwerze.
źródło