Bir Thread veya Timer'da HttpServerUtility.MapPath yöntemine nasıl erişilir?


89

Bir kullanmak System.Timers.Timerbenim Asp.Net uygulamasında ve kullanmak gerekmez HttpServerUtility.MapPathyoluyla yalnızca görünüyor yöntemi HttpContext.Current.Server.MapPath. Sorun olduğunu HttpContext.Currentise nullzaman Timer.Elapsedolayı harekete.

Bir HttpServerUtility nesnesine başvuru almanın başka bir yolu var mı? Bunu sınıfımın yapıcısına enjekte edebilirim. Güvenli mi ? Mevcut talebin sonunda Çöp Toplanmayacağından nasıl emin olabilirim?

Teşekkürler!

Yanıtlar:


143

Kullanımı mümkün HostingEnvironment.MapPath()yerineHttpContext.Current.Server.MapPath()

Henüz bir iş parçacığı veya zamanlayıcı etkinliğinde denemedim.


Düşündüğüm bazı (uygulanabilir olmayan) çözümler;

  • Ben yaklaşık on care tek yöntem HttpServerUtilityolduğunu MapPath. Dolayısıyla alternatif olarak AppDomain.CurrentDomain.BaseDirectoryyollarımı bundan kullanabilir ve inşa edebilirim . Ancak uygulamanız sanal dizinler kullanıyorsa bu başarısız olur (Benimki yapar).

  • Başka bir yaklaşım: GlobalSınıfa ihtiyacım olan tüm yolları ekleyin . Bu yolları içinde çözün Application_Start.


1
Bununla birlikte, yukarıdakilerin IIS'nin sonraki sürümlerinde çalışmadığını unutmayın. IIS7'de uygulama başlangıcı bir http talebinin dışında çağrılabilir. Yani kod örneği. Eminim HostingEnvironment.MapPath () hala daha önce olduğu gibi çalışacaktır.
Robba

Ancak HostingEnvironment.MapPath (), klasör yolunu doğrudan almak için onu iletirseniz ve boş bir dizge verirseniz bir hata verir ... HttpContext.Current.Server.MapPath (""); -> HostingEnvironment.MapPath (""); -> hatayı artırıyor
VSP

14

Bunun sanal dizinler sorununuzu çözüp çözmeyeceğini bilmiyorum, ancak bunu MapPath için kullanıyorum:

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

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

path.Replace ( "~", string.Empty) (, '~' '') path.Replace olmalıdır
Slava

13

HostingEnvironment mükemmel bir çözüm değildir çünkü alay edilmesi çok zor bir sınıftır (bkz. HostingEnvironment kullanan kodu birim test etme. . ).

Test edilebilir bir ihtiyacı olanlar için, daha iyi bir yolu önerdiği gibi kendi yolunu-mapper arayüz oluşturmak için olabilir https://stackoverflow.com/a/1231962/85196 olarak bunu uygulamaya hariç

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

Sonuç kolayca alay edilebilir, dahili olarak HostingEnvironment'ı kullanır ve hatta potansiyel olarak ase69s'un endişelerini aynı anda ele alabilir.


Bu, başvurduğu kitaplıkta System.Web veya System.Net'e bağımlılık gerektirmeden bir Web API projesi için yol çözümlemesi için bir uygulama sağlamama izin verdi. +1
David Peterson

DI ve bu yaklaşımın
Test Edilebilirliği için beğeniler

2

Zamanlayıcıyı başlatmadan önce MapPath işlevini çağırıp sonucu önbelleğe alamaz mısınız? MapPath çağrısının tick olayı içinde olması kesinlikle gerekli mi?


2

Zamanlayıcı geçtiğinde, geçerli bir HTTP bağlamı yoktur. Bunun nedeni, zamanlayıcı olaylarının belirli bir HTTP isteğiyle ilişkili olmamasıdır.

Yapmanız gereken, HTTP bağlamının mevcut olduğu HttpServerUtility.MapPath kullanmaktır. Bunu istek kanalı olaylarından birinde (Page_Load gibi) veya Application_Start gibi bir Global.asax olayında yapabilirsiniz.

MapPath sonucunu, ihtiyaç duyduğunuz belirli bir dosyanın konumunu almak için Path.Combine'ı kullanabileceğiniz Timer.Elapsed olayından erişilebilen bir değişkene atayın.


0

Bence o anda boş olmasının nedeni (eğer düşünürseniz), zamanlayıcı geçen olayının bir HTTP isteğinin parçası olarak gerçekleşmemesi (dolayısıyla bağlam yoktur). Sunucunuzdaki bir şeyden kaynaklanır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.