How to access the HttpServerUtility.MapPath method in a Thread or Timer?

前端 未结 6 1878
梦毁少年i
梦毁少年i 2020-12-23 15:46

I use a System.Timers.Timer in my Asp.Net application and I need to use the HttpServerUtility.MapPath method which seems to be only available via <

相关标签:
6条回答
  • 2020-12-23 16:16

    It's possible to use HostingEnvironment.MapPath() instead of HttpContext.Current.Server.MapPath()

    I haven't tried it yet in a thread or timer event though.


    Some (non viable) solutions I considered;

    • The only method I care about on HttpServerUtility is MapPath. So as an alternative I could use AppDomain.CurrentDomain.BaseDirectory and build my paths from this. But this will fail if your app uses virtual directories (Mine does).

    • Another approach: Add all the paths I need to the the Global class. Resolve these paths in Application_Start.

    0 讨论(0)
  • 2020-12-23 16:18

    Can you not call the MapPath function before starting the timer, and simply cache the result? Is it absolutely neccessary to have the MapPath call inside the tick event?

    0 讨论(0)
  • I think the reason for why it is null at that time (if you think about it), is that the timer elapsed event doesn't occur as part of a HTTP request (hence there is no context). It is caused by something on your server.

    0 讨论(0)
  • 2020-12-23 16:30

    When the timer elapse, there is no current HTTP context. This is because the timer events are not related to a specific HTTP request.

    What you should do is use HttpServerUtility.MapPath where HTTP context is available. You can do it in one of the request pipeline events (such as Page_Load) or in a Global.asax event such as Application_Start.

    Assign the MapPath result to a variable accessible from the Timer.Elapsed event, where you could use Path.Combine to get the location of a specific file you need.

    0 讨论(0)
  • 2020-12-23 16:32

    I don't know if this will solve your virtual directories issue, but I use this for 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 讨论(0)
  • 2020-12-23 16:32

    HostingEnvironment isn't the perfect solution because it's a very difficult class to mock (see How to unit test code that uses HostingEnvironment.MapPath).

    For those who need testability, a better way might be to create your own path-mapper interface as proposed by https://stackoverflow.com/a/1231962/85196, except implement it as

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

    The result is easily mockable, uses HostingEnvironment internally, and could even potentially address ase69s's concern at the same time.

    0 讨论(0)
提交回复
热议问题