我用一个 System.Timers.Timer 我Asp.Net 应用程序和我需要用 HttpServerUtility.MapPath 方法,该方法似乎只能通过 HttpContext.Current.Server.MapPath.问题是, HttpContext.CurrentnullTimer.Elapsed 事件发生火灾。

是否有另一种方式得到一个参考HttpServerUtility对象?我可以将它注入我的类的构造。这是安全的吗?我怎样才能确定这不会是垃圾收集在结束目前的请求?

谢谢!

有帮助吗?

解决方案

这有可能使用 HostingEnvironment.MapPath() 而不是的 HttpContext.Current.Server.MapPath()

我还没有尝试过在线或计时器事件。


一些(非行)的解决方案我认为;

  • 唯一的方法我关心上 HttpServerUtilityMapPath.所以作为一种替代,我可以使用 AppDomain.CurrentDomain.BaseDirectory 和建立我的路径,从这一点。 但是这样会失败,如果你的应用程序使用虚拟目录 (我).

  • 另一个办法:添加所有的路径,我需要的 Global 类。解决这些路中 Application_Start.

其他提示

我不知道这是否会解决您的虚拟目录问题,但我将其用于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不是一个完美的解决方案,因为它是一个非常难以模拟的类(参见如何对使用HostingEnvironment.MapPath的代码进行单元测试

对于那些需要可测试性的人来说,更好的方法可能是按照 https:// stackoverflow的建议创建自己的路径映射器界面.com / a / 1231962/85196 ,除了将其实现为

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

结果很容易模拟,在内部使用HostingEnvironment,甚至可以解决 ase69s同时关注

在启动计时器之前,你不能调用MapPath函数,只是缓存结果吗?在tick事件中进行MapPath调用是否绝对必要?

当计时器过去时,没有当前的HTTP上下文。这是因为计时器事件与特定的HTTP请求无关。

你应该做的是使用HTTP上下文可用的HttpServerUtility.MapPath。您可以在其中一个请求管道事件(例如Page_Load)或Global.asax事件(例如Application_Start)中执行此操作。

将MapPath结果分配给可从Timer.Elapsed事件访问的变量,您可以使用Path.Combine获取所需特定文件的位置。

我认为当时为什么它为空(如果你考虑的话)的原因是,定时器经过的事件不会作为HTTP请求的一部分发生(因此没有上下文)。它是由您服务器上的某些内容引起的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top