Windows Form中通过JSON获取天气图标失败问题求助
问题:C# WinForm调用OpenWeatherMap API无法加载天气图标
开发C# Windows Form程序时,使用Newtonsoft JSON调用OpenWeatherMap API可正常获取温度、湿度等数据,但天气图标无法显示,无报错信息。核心代码、数据模型和测试JSON如下:
主类核心代码
void getweather() { using (WebClient web = new WebClient()) { string url = string.Format("https://api.openweathermap.org/data/2.5/weather?lat=-42.15&lon=-12.9167&appid=4ef889ce24xxxxxx4b&units=metric&cnt=6"); var json = web.DownloadString(url); WeatherInfo.Root Info = JsonConvert.DeserializeObject<WeatherInfo.Root>(json); STRGRADOS.Text = string.Format("{0} °" + "C", Info.main.temp); pic_icon.ImageLocation = "https://openweathermap.org/img/w/" + Info.weather[0].icon+".PNG"; HUMEDAD.Text = string.Format("{0}", Info.main.humidity + "%"); Console.WriteLine(Info); } }
数据模型类
class WeatherInfo{ public class Weather { public int id { get; set; } public string main { get; set; } public string description { get; set; } public string icon { get; set; } } public class Root { public Coord coord { get; set; } public List<Weather> weather { get; set; } public string @base { get; set; } public Main main { get; set; } public int visibility { get; set; } public Wind wind { get; set; } public Clouds clouds { get; set; } public int dt { get; set; } public Sys sys { get; set; } public int timezone { get; set; } public int id { get; set; } public string name { get; set; } public int cod { get; set; } } }
测试用JSON
{"coord":{"lon":-32.9167,"lat":-12.15},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":25.26,"feels_like":25.64,"temp_min":25.26,"temp_max":25.26,"pressure":1018,"humidity":69,"sea_level":1018,"grnd_level":1018},"visibility":10000,"wind":{"speed":7.82,"deg":166,"gust":7.68},"clouds":{"all":79},"dt":1688501669,"sys":{"sunrise":1688459581,"sunset":1688500721},"timezone":-7200,"id":0,"name":"","cod":200}
排查出的问题
- URL大小写敏感:OpenWeatherMap的图标后缀为小写
.png,代码中使用的.PNG会导致部分环境下无法匹配资源。 - 控件未强制刷新:WinForm的PictureBox设置
ImageLocation后,异步加载可能未触发界面刷新。 - 缺失模型子类:原数据模型未定义
Coord、Main等子类,虽不影响已有数据获取,但存在潜在反序列化风险。 - TLS版本兼容:OpenWeatherMap要求使用TLS 1.2及以上,部分旧环境默认TLS版本过低会导致HTTPS请求失败。
修复方案及完整示例
1. 修正图标URL并强制刷新控件
将后缀改为小写.png,设置ImageLocation后调用Refresh()强制更新界面。
2. 补充完整数据模型
添加缺失的Coord、Main等子类,确保反序列化完整。
3. 指定TLS版本
在请求前设置TLS 1.2,解决HTTPS访问问题。
4. 增加异常捕获
捕获请求及加载过程中的异常,便于排查问题。
修复后主类代码
void getweather() { // 指定TLS版本,解决HTTPS访问限制 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; using (WebClient web = new WebClient()) { string url = string.Format("https://api.openweathermap.org/data/2.5/weather?lat=-42.15&lon=-12.9167&appid=4ef889ce24xxxxxx4b&units=metric&cnt=6"); try { var json = web.DownloadString(url); WeatherInfo.Root Info = JsonConvert.DeserializeObject<WeatherInfo.Root>(json); STRGRADOS.Text = string.Format("{0} °C", Info.main.temp); HUMEDAD.Text = string.Format("{0}%", Info.main.humidity); // 修正图标URL大小写 string iconUrl = $"https://openweathermap.org/img/w/{Info.weather[0].icon}.png"; pic_icon.ImageLocation = iconUrl; // 强制刷新控件 pic_icon.Refresh(); Console.WriteLine(Info); } catch (Exception ex) { Console.WriteLine($"加载出错:{ex.Message}"); } } }
完整数据模型类
class WeatherInfo { public class Coord { public double lon { get; set; } public double lat { get; set; } } public class Weather { public int id { get; set; } public string main { get; set; } public string description { get; set; } public string icon { get; set; } } public class Main { public double temp { get; set; } public double feels_like { get; set; } public double temp_min { get; set; } public double temp_max { get; set; } public int pressure { get; set; } public int humidity { get; set; } public int sea_level { get; set; } public int grnd_level { get; set; } } public class Wind { public double speed { get; set; } public int deg { get; set; } public double gust { get; set; } } public class Clouds { public int all { get; set; } } public class Sys { public int sunrise { get; set; } public int sunset { get; set; } } public class Root { public Coord coord { get; set; } public List<Weather> weather { get; set; } public string @base { get; set; } public Main main { get; set; } public int visibility { get; set; } public Wind wind { get; set; } public Clouds clouds { get; set; } public int dt { get; set; } public Sys sys { get; set; } public int timezone { get; set; } public int id { get; set; } public string name { get; set; } public int cod { get; set; } } }
额外备选方案
若仍无法加载,可尝试直接下载图标到内存流再加载:
// 替换原图标加载代码 string iconUrl = $"https://openweathermap.org/img/w/{Info.weather[0].icon}.png"; using (var stream = web.OpenRead(iconUrl)) { pic_icon.Image = Image.FromStream(stream); }
内容的提问来源于stack exchange,提问作者jim root
相关产品推荐
相关产品推荐

