2008-09-21 68 views
86

我在Asp.Net應用程序中使用System.Timers.Timer,我需要使用HttpServerUtility.MapPath方法,似乎只有通過HttpContext.Current.Server.MapPath可用。 問題是HttpContext.CurrentnullTimer.Elapsed事件觸發。如何訪問Thread或Timer中的HttpServerUtility.MapPath方法?

是否有另一種方式來獲得一個HttpServerUtility對象的引用? 我可以在我的類的構造函數中注入它。它安全嗎?我如何確定它不會在當前請求結束時收集垃圾?

謝謝!

回答

138

有可能使用的HostingEnvironment.MapPath()代替HttpContext.Current.Server.MapPath()

我沒有在一個線程或定時器事件嘗試過呢,雖然。


我考慮過的一些(不可行的)解決方案;

  • 我關心的HttpServerUtility的唯一方法是MapPath。所以作爲替代方案,我可以使用AppDomain.CurrentDomain.BaseDirectory並從中建立我的路徑。 但是,如果你的應用程序使用虛擬目錄(我的),這將失敗。

  • 另一種方法: 將所需的所有路徑添加到Global類。在Application_Start中解決這些路徑。

+1

但是,請注意上述不適用於更高版本的IIS。在IIS7中,應用程序啓動可能在http請求之外被調用。也就是代碼示例。我確信HostingEnvironment.MapPath()仍然像以前一樣工作。 – Robba 2010-10-25 13:44:58

+0

但HostingEnvironment.MapPath()給出錯誤,如果你傳遞它並且爲了直接獲得文件夾路徑而使用空字符串... HttpContext.Current.Server.MapPath(「」); - > works HostingEnvironment.MapPath(「」); - >引發錯誤 – VSP 2012-03-02 10:11:55

0

我覺得爲什麼它是空在那個時候(如果你認爲這件事),是計時器經過事件不會發生作爲HTTP請求的一部分(因此沒有上下文)的原因。這是由您的服務器上的某些內容引起的。

2

你能不能啓動定時器之前調用MapPath的功能,只是緩存結果?在tick事件中使用MapPath調用是否絕對必要?

2

當計時器過去時,沒有當前的HTTP上下文。這是因爲計時器事件與特定的HTTP請求無關。

你應該做的是使用HttpServerUtility.MapPath其中HTTP上下文可用。您可以在請求管道事件之一(如Page_Load)或Global.asax事件(如Application_Start)中執行此操作。

將MapPath結果分配給可從Timer.Elapsed事件訪問的變量,您可以在其中使用Path.Combine獲取所需的特定文件的位置。

14

我不知道這是否會解決您的虛擬目錄的問題,但我用這個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

path.Replace(「〜」,string.Empty) 應該是path.Replace('〜','。') – Slava 2016-03-18 14:17:37

13

HostingEnvironment是不完美的解決方案,因爲它是一個非常困難的類嘲笑(見How to unit test code that uses HostingEnvironment.MapPath)。

對於那些誰需要的可測性,更好的方法可能是創建自己的路徑映射器接口所提議的https://stackoverflow.com/a/1231962/85196,除了實現它作爲

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

結果是容易mockable,使用HostingEnvironment內部,和甚至可能會同時處理ase69s's concern