When a web application is sitting behind either a proxy or a load balancer, and you use Request.Url
to, for example, generate an absolute url, you would get a the private url used by proxy to connect to the web server.
The reason
Let's see how a typical load balanced environment works:
- The user types
http://example.com
; - The request goes to the load balancer which is configured to respond to that url;
- Then the load balancer, randomly or with some logic, forwards the request to the real server that will generate the response, and will do so by using some internal urls, for example server1.mydomain.int or even directly with some internal IP address. Maybe there is a farm with 100s sites on it, and each site might have a port number to identify it.
- finally the web server responds to the request which has been addressed to
http://server1.mydomain.int:8045
By default, the Url
property is generated using the information provided by the web server, which is fine in most cases, where the public url is directly mapped to the web server. But in this scenario, it will returnhttp://server1.mydomain.int:8045
instead of http://example.com
.
The solution
The solution is pretty simple but not very well documented. All you need it is to add an aspnet
specific setting in the appSettings
section of the web.config
file.
The property is called aspnet:UseHostHeaderForRequestUrl
and by default its value is false
. When set to true
, the Url
property will be built using the Host
header of the request instead of the domain the server is responding to.
You can read more about this property and all other "secret" configuration keys on the MSDN site.