6

I have some kind of a job scheduling implemented which calls a function ProcessJob. Now inside this method I need to generate url to one of my pages i.e DoanloadPage.aspx?some_params. That url is sent to user via email and when user clicks that link, it will take to the page.

The problem here is that I am not generating url in a web request method or I don't have access to the Request object. URL need to be generated in a custom class which is threaded i.e not in a web request.

So I can't go with these solutions:

HostingEnvironment.MapPath("test.aspx");
VirtualPathUtility.ToAbsolute("123.aspx");
HttpContext.Current.Request.Url.Authority;

None of these works because I think they all rely on current request or session somehow. So how do I generate urls for my app inside my code so I can use them anyway I want.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Waleed
  • 1,097
  • 18
  • 45
  • SImply hardcoding the domain is not an option? – VDWWD Sep 17 '18 at 06:30
  • @VDWWD yeah but we are on test environment right now and not going to deploy for a few months. – Waleed Sep 17 '18 at 06:40
  • If your method cannot use `HttpContext.Current.Request.Url`, for example in case it's a background scheduled task, then you can use get the URL in the first request in `Application_BeginRequest` and use it in your class. As another option, if you don't want or cannot rely on `Application_BeginRequest`, you can store the URL in a setting (like appsettings) and use it in your class. – Reza Aghaei Sep 17 '18 at 17:08

3 Answers3

4

If your method cannot use HttpContext.Current.Request.Url, for example in case it's a background scheduled task, then you can use either of the following options:

  • In case that your code is hosted in the same ASP.NET application, you can pass the site domain name of the site to your class, in the first request. To do so, you need to handle Application_BeginRequest event and get the domain from HttpContext.Current.Request.Url and then pass it to your class, or store it in an application scope storage. You can find an implementation in this post or the original article.
    Note: The code is available in SO, so I don't repeat the code here.

  • If your code is not hosted in the same ASP.NET application or if for any reason you don't want to rely on Application_BeginRequest, as another option you can store the site domain name in a setting (like appsettigs in app.condig or web.config if it's web app) and use it in your code.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
0

You can do something like this. Dns.GetHostName will return the name of the computer that is hosting the site. You can use that to check if the site is on a development server.

string domain = "www.productionurl/123.aspx";

if (Dns.GetHostName() == "Development")
{
    domain = "www.developmenturl/123.aspx";
}

The Dns.GetHostName() is not the only way to check. You could also use the HostingEnvironment.ApplicationPhysicalPath. You can check that also and see if the path is that of the development server.

VDWWD
  • 35,079
  • 22
  • 62
  • 79
0

My answer is: don't do this. You're building a distributed system, albeit a simple one, and generally speaking it is problematic to introduce coupling between services in a distributed system. So even though it is possible to seed your domain using Application_BeginRequest, you are then tying the behavior of your batch job to your web site. With this arrangement you risk propagating errors and you make deployment of your system more complicated.

A better way to look at this problem is to realize that the core desire is to synchronize the binding of your production site with the URL that is used in your batch job. In many cases an entry in the app.config of your batch would be the best solution, there really isn't any need to introduce code unless you know that your URL will be changing frequently or you will need to scale to many different arbitrary URLs. If you have a need to support changing the URL programmatically, I recommend you look at setting up a distributed configuration system like Consul and read the current URLs from your deployment system for both the IIS binding and the app.config file for your batch. So even in this advanced scenario, there's no direct interaction between your batch and your web site.

Paul Keister
  • 12,851
  • 5
  • 46
  • 75
  • Second option in this [answer](https://stackoverflow.com/a/52372581/3110834) is pointing to the same solution - using settings – Reza Aghaei Sep 23 '18 at 16:39