Reputation: 181
I want to register my WebAPI to Consul service discovery and for that I should provide URL of my WebAPI (for example: http://service1.com) and health check endpoint (http://service1.com/health/check). How can I get that URL?
I found this piece of code:
var features = app.Properties["server.Features"] as FeatureCollection;
var addresses = features.Get<IServerAddressesFeature>();
var address = addresses.Addresses.First();
var uri = new Uri(address);
It returns 127.0.0.1:16478 instead of localhost:5600. I think first one used by dotnet.exe and second one is IIS which forwards 5600 to 16478. How can I get localhost:5600 in Startup.cs?
Upvotes: 18
Views: 21644
Reputation: 21709
EDIT: I reread your question. You wanted to know how to do this in Startup.cs
. You can, but with fewer fallbacks. Your only choices are configuration or raw DNS.GetHostName()
, which are less than ideal. Instead, upon any request to your service, lazily register your API. This is when you have context. Prior to that, your service knows nothing Jon Snow. The first request to your API is likely going to be health-checks, so that will kick off your registration with consul.
A solution I've used is a combination of configuration and headers in a fallback scenario.
Rely first on the X-Forwarded-For header. If there are cases where that doesn't apply or you have a need to... you can fallback to configuration.
This works for your use case, discovery. That said, it also works when you want to generate links for any reason, (e.g. for hypermedia for JSON API or your own REST implementation).
The fallback can be useful when there are reconfigurations occuring, and you have a dynamic configuration source that doesn't require a redeployment.
In the ASP.NET Core world, you can create a class and inject it into your controllers and services. This class would have a method that knows to try config first (to see if overriding is needed) and then the X-Forwarded-For header, and if neither is appropriate, fallback further to HttpContext.Request
to get relevant URI parts.
What you're doing is enabling your API to be contextless and resiliency (to change) by giving it some contextual awareness of where "it lives".
Upvotes: 3
Reputation: 1330
This happens when you try to get current URL in Startup.cs. I've faced this issue before. What i did as Solution for my problem is. I Just declared Custom Setting in AppSettings in web.config(For Local) file and web.release.config(For Live) like following
in web.config
<appSettings>
<add key="MyHost" value="http://localhost:5600" />
</appSettings>
in web.release.config
<appSettings>
<add key="MyHost" value="http://myLiveURL.com" />
</appSettings>
in startup.cs
string hostSetting = ConfigurationSettings.AppSettings["MyHost"];
And different host in release file. so what it helped is i can get Localhost URL in local website from web.config and Live URL from web.release.config.
if you are using Azure for live. it will be more easier for live(you would not need to add setting web.release.config file). add app setting in your website application setting https://learn.microsoft.com/en-us/azure/app-service/configure-common
In Case of ASP.NET Core you can use appsettings.json instead of web.config
Upvotes: -5
Reputation: 1334
Well, there are multiple solutions for this problem. Your address is this:
string myurl = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}";
It returns 127.0.0.1:16478 instead of localhost:5600
You got this right yes. One is from IIS and one from dotnet. So, you have a problem of trying to get correct url. Ok, so what happens if you service is behind reverse proxy? https://en.wikipedia.org/wiki/Reverse_proxy
Then your service will not be exposed directly to internet, but requests made to specific url will be passed from reverse proxy to your service. Also, you can configure reverse proxy to forward additional headers that are specifying where the original request came from. I think that most reverse proxies are using X-Forwarded-For
(Some of them are using X-Original-Host
etc).
So if you have proper header set on RP, then you can get url like this:
url = url.RequestContext.HttpContext.Request.Headers["X-Forwarded-For"]
Url is of type UrlHelper. To simplify this method, you can create extension method (GetHostname(this UrlHelper url)) and then us it in your controller or wherever you want. Hope it helps
Upvotes: 13
Reputation: 6924
I don't think it is possible since there is usually a reverse proxy in production that handles public address and the application itself should not be exposed to public and, therefore, be aware of public address. But there can be some workarounds:
Upvotes: 8