在Startup.cs中获取ASP.NET Core 2.1当前Web主机名和端口

18

我希望将我的WebAPI注册到 Consul 服务发现中,为此我需要提供我的WebAPI的URL(例如:http://service1.com)和健康检查端点(http://service1.com/health/check)。我应该如何获取这个URL?

我找到了以下代码:

var features = app.Properties["server.Features"] as FeatureCollection;
var addresses = features.Get<IServerAddressesFeature>();
var address = addresses.Addresses.First();               
var uri = new Uri(address);

在Startup.cs中如何获取localhost:5600?它返回的是127.0.0.1:16478而不是localhost:5600。我认为第一个地址被dotnet.exe使用,第二个地址是由IIS将5600转发到16478。


嗨,我这里也有同样的问题。如果我在IIS中启动,地址是NULL。如果我选择项目调试模式,则是完整的。有什么帮助吗? - federico scamuzzi
看起来这是一个无法解决的问题。谁会想到 :/ - Jonik
4个回答

13

嗯,对于这个问题有多种解决方案。你的地址是:

string myurl = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}";

它返回的是127.0.0.1:16478,而不是localhost:5600。这个没错,一个来自IIS,一个来自dotnet。所以,你试图获取正确的url时遇到了问题。好的,那么如果你的服务在反向代理后面会发生什么?https://en.wikipedia.org/wiki/Reverse_proxy那么你的服务将不会直接暴露在互联网上,但是针对特定url的请求将从反向代理传递到您的服务。此外,您可以配置反向代理以转发附加的标头,这些标头指定了原始请求的来源位置。我认为大多数反向代理都使用X-Forwarded-For(其中一些使用X-Original-Host等)。因此,如果在RP上设置了正确的标头,则可以像这样获取url:
url = url.RequestContext.HttpContext.Request.Headers["X-Forwarded-For"]

Url是UrlHelper类型。为了简化此方法,您可以创建扩展方法(GetHostname(this UrlHelper url)),然后在控制器或任何其他地方使用它。希望这有所帮助。


8

我认为这是不可能的,因为在生产环境中通常会有反向代理来处理公共地址,应用程序本身不应该面向公众并且不应意识到公共地址。但是可以有一些变通方法:

  1. 将URL放置在某种配置文件中,可以在部署步骤期间更新以具有正确的URL。
  2. 应用程序可以获取请求的完整URL 如此,因此在首次实际请求应用程序后,我们可以获取主机名。

3
编辑: 我重新阅读了您的问题。您想知道如何在Startup.cs中执行此操作。您可以这样做,但是可供选择的后备方案较少。您唯一的选择是配置或原始的DNS.GetHostName(),这些都不太理想。相反,在对您的服务进行任何请求时,懒惰地注册您的API。这是您拥有上下文的时候。在此之前,您的服务对Jon Snow一无所知。对于您的API的第一个请求很可能是健康检查,因此这将启动您与consul的注册。

我使用的解决方案是配置和回退方案中的标头的组合。

首先依赖于X-Forwarded-For标头。如果有某些情况不适用或您需要...您可以回退到配置。

这适用于您的用例发现。话虽如此,当您想出于任何原因生成链接时,它也适用于您(例如,为JSON API或自己的REST实现生成超媒体)。

当重新配置发生时,回退功能可以很有用,并且您拥有一个动态配置源,不需要重新部署。

在ASP.NET Core中,您可以创建一个类并将其注入到控制器和服务中。这个类会有一个方法,它知道首先尝试配置(以查看是否需要覆盖),然后是X-Forwarded-For标头,如果都不适用,则进一步回退到HttpContext.Request来获取相关的URI部分。

您正在做的是通过使其具有一些上下文意识来使您的API无需上下文并具有弹性(以应对变化)。


-5

当你在Startup.cs中尝试获取当前URL时,就会出现这种情况。我以前也遇到过这个问题。我为我的问题提供的解决方案是:在web.config(本地)文件和web.release.config(线上)文件中声明自定义设置,如下所示:


在 web.config 中

<appSettings>
    <add key="MyHost" value="http://localhost:5600" />
</appSettings>

在web.release.config文件中

<appSettings>
    <add key="MyHost" value="http://myLiveURL.com" />
</appSettings>

在 startup.cs 中

string hostSetting = ConfigurationSettings.AppSettings["MyHost"];

发布文件中有不同的主机。所以它帮助我可以从 web.config 中获取本地网站的 Localhost URL,从 web.release.config 中获取 Live URL。

如果您在使用 Azure 进行实时操作,则更容易进行实时操作(您无需添加设置 web.release.config 文件)。在您的网站应用程序设置中添加应用程序设置 https://learn.microsoft.com/en-us/azure/app-service/configure-common

对于 ASP.NET Core,您可以使用 appsettings.json 替代 web.config


ASP.NET Core没有web.config文件,而是使用appsettings.json。 - Jonik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接