不知道这样的主机。(使用 HttpClient 从 Web API 控制器调用天气 API)

No such host is known.(calling weatherAPI from webapi controller using HttpClient)

我正在尝试从 asp.net WebAPI 调用 openWeatherApi。当我从前端收到一个城市的名字时,我用它来从数据库中查找 city/airport。然后,我用机场的纬度和经度来调用开放天气API。我想用响应做进一步的计算和预测。

我的代码是:

HttpClient client = new HttpClient();

try
                {
                    client.BaseAddress = new Uri("http://api.openweather.org");
                     var response = await client.GetAsync($"/data/2.5/weather?lat={airport.AirportLatitude}&lon={airport.AirportLongitude}&appid={apiKey}");
                  //  var response = await // client.GetAsync($"/data/2.5/weather?q=London,uk&appid={apiKey}");
                    response.EnsureSuccessStatusCode();

                    var stringResult = await response.Content.ReadAsStringAsync();
                    var rawWeather = JsonConvert.DeserializeObject<OpenWeatherResponse>(stringResult);
                    System.Console.WriteLine("$$$$$$$$$$$After API call made$$$$$$$$$$$$$$$");
                    System.Console.WriteLine(response);
                    return Ok(new {
                        Temp = rawWeather.Main.Temp,
                        Summary = string.Join(",", rawWeather.Weather.Select(x=>x.Main)),
                        City = rawWeather.Name
                    });
                    // return Ok(response);
                }

                catch(HttpRequestException httpRequestException)
                {   
                    System.Console.WriteLine(httpRequestException.Message); 
                    return BadRequest($"Error getting weather : {httpRequestException.Message}");
                }

当我 运行 这个应用程序时,有时我会收到 400BadRequest,有时我会收到 500:Internal 服务器错误

1) 不知道这样的主机。 2)System.InvalidOperationException:该实例已经发起了一个或多个请求。只能在发送第一个请求之前修改属性。

Startup.cs

services.AddTransient<HttpClient>(); 
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

当我尝试将完整的 openweather url 放入我的浏览器时,它 returns json,但是当我尝试从 [=33] 运行 时出现错误=] 核心网络 Api 控制器。

如有任何帮助,我们将不胜感激。

提前致谢

您应该使用 using 语句

using (var client = new HttpClient())
{
          try
            {
                client.BaseAddress = new Uri("http://api.openweather.org");
                 var response = await client.GetAsync($"/data/2.5/weather?lat={airport.AirportLatitude}&lon={airport.AirportLongitude}&appid={apiKey}");
              //  var response = await // client.GetAsync($"/data/2.5/weather?q=London,uk&appid={apiKey}");
                response.EnsureSuccessStatusCode();

                var stringResult = await response.Content.ReadAsStringAsync();
                var rawWeather = JsonConvert.DeserializeObject<OpenWeatherResponse>(stringResult);
                System.Console.WriteLine("$$$$$$$$$$$After API call made$$$$$$$$$$$$$$$");
                System.Console.WriteLine(response);
                return Ok(new {
                    Temp = rawWeather.Main.Temp,
                    Summary = string.Join(",", rawWeather.Weather.Select(x=>x.Main)),
                    City = rawWeather.Name
                });
                // return Ok(response);
            }

            catch(HttpRequestException httpRequestException)
            {   
                System.Console.WriteLine(httpRequestException.Message); 
                return BadRequest($"Error getting weather : {httpRequestException.Message}");
            }
}

已接受的答案是错误且危险的 - 您永远不应将 HttpClient 包裹在 using 块中,因为它会在大量使用期间导致端口耗尽。

有关这方面的更多详细信息,您可以查看此 Microsoft 认可的博客 post:You're using HttpClient wrong and it is destabilizing your software

此外,来自 this article from Microsoft

There's a very good chance that, every time you need to access a Web Service, you've been creating an HttpClient object and then throwing it away. Unfortunately, that's bad for your application because you can run out of WebSockets (yes, even if you call the object's Dispose method before discarding it). Though, I have to admit, you'll only have this problem if you use the HttpClient a lot. Still, it's a bad idea to keep creating and destroying it.

In the .NET Framework, the intent was for you to create the HttpClient once in your application and use it over and over. To do that you'll have to declare your HttpClient object as a global or static variable. That creates its own problems, of course.

In ASP.NET Core, however, you have a better option: the HttpClientFactory. The HttpClientFactory provides you with HttpClient objects but takes responsibility for managing the resources that the clients can use up. Think of it as "connection pooling for Web Services."

因此,在桌面应用程序中,使用 HttpClient 作为 public 静态变量或将其包装在单例中。在 ASP.NET 核心应用程序中,使用 the built-in factory 创建 HttpClient 个实例。