2008-09-21 35 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