Alexei - check Codidact
Alexei - check Codidact

Reputation: 23078

Why current ASP.NET MVC application root virtual path is not available in a another thread/Task?

One of my recent projects involved sending reminder e-mails based on some reminder configuration. E-mail sending is implemented in an asynchronous job using Quartz.net. and it requires to include a permalink to a entity in the application.

However, in order to get this permalink, I have to be able to compute the full URL, based on the identifier stored in the queue used for the job. The answer is not straightforward, since HttpContext is not available in the thread's context.

One solution is to store application root path in the queue and use it from there. Another way is to use a function like the following:

public static String GetCurrentBasePath(String prefix = "http://")
{
   return String.Format("{0}{1}{2}", 
      prefix,                                           // protocol
      System.Net.Dns.GetHostEntry("").HostName,         // host
      System.Web.HttpRuntime.AppDomainAppVirtualPath    // virtual application path
   );
}

However, this has (severe) limitations, since the protocol must be provided and also returns the hostname, not the domain name, thus rendering it useless when having multiple Web applications bound to the same host.

The question: is Web application base path available in another thread/task?. I think the other thread/task context is somehow connected to the ApplicationPool, rather than the WebApp and since multiple WebApps can use the same ApplicationPool, there is not a direct connection between thread context and the WebApp.

Upvotes: 0

Views: 244

Answers (1)

pim
pim

Reputation: 12577

I'm not sure how you're invoking this. But from my experience, parallelism (as you've mentioned) loses the HttpContext. That said, there is nothing to stop you from using a config variable with the string value(s) that you need. Of course, depending how dynamic this value is this might not be the best course of action. But remember that the computation you're making above is expensive, so remember to store the value locally.

I believe the best solution here (assuming you know the context values, which I don't see why you couldn't/wouldn't) would be to set some variables and avoid the computation altogether.

static readonly string hostName = "your-host";
static readonly string virtualPath = "your-virtual-path";
public static String GetCurrentBasePath(String prefix = "http://")
{
   return String.Format("{0}{1}{2}", 
      prefix,                                           // protocol
      hostName,         // host
      virtualPath    // virtual application path
   );
}

Upvotes: 0

Related Questions