C#加载OpenWeatherAPI数据并注入_Layout访问嵌套属性的方法
要通过强类型访问嵌套属性,你需要为每一层嵌套的JSON结构定义对应的C#类,也可以选择用动态类型方案跳过类定义。
一、先修复现有代码的异步逻辑问题
你当前的WeatherApiResult方法存在严重的异步误用:启动任务后没有等待执行完成就直接返回weather变量,大概率会拿到空值,后续调用.Result还容易在ASP.NET环境下触发线程死锁。
优化后的方法写法:
public async Task<Weather> WeatherApiResult() { string city = Weather(); string apiKey = "你的密钥"; string requestUrl = $"https://api.openweathermap.org/data/2.5/weather?q={city}&units=metric&appid={apiKey}"; using var httpClient = new HttpClient(); // 注:OpenWeather不需要在请求头传密钥,你原本加的Authorization头是无效的,可以直接删除 var httpResponse = await httpClient.GetAsync(requestUrl); httpResponse.EnsureSuccessStatusCode(); var responseContent = await httpResponse.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Weather>(responseContent); }
页面调用时直接用await,不要用.Result:
@{ var weather = await settingsService.WeatherApiResult(); <p>城市:@weather.name</p> <p>温度:@weather.main.temp °C</p> <p>时区:@weather.timezone</p> }
二、嵌套属性的访问方案
方案1:定义完整的强类型类(推荐)
你需要匹配OpenWeather返回的JSON结构,为每一层嵌套对象定义对应类,示例如下:
// 根对象 public class WeatherRoot { public string name { get; set; } public int timezone { get; set; } public int id { get; set; } public int cod { get; set; } // 嵌套的气温相关对象 public Main main { get; set; } // 嵌套的风力相关对象 public Wind wind { get; set; } // 嵌套的天气状况数组 public List<WeatherItem> weather { 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 class Wind { public double speed { get; set; } public int deg { get; set; } } // 天气状况类 public class WeatherItem { public int id { get; set; } public string main { get; set; } public string description { get; set; } public string icon { get; set; } }
定义完成后,把反序列化的目标类型改成WeatherRoot即可直接通过weather.main.temp访问嵌套属性,有编译时类型检查,不容易出错。
方案2:用动态类型跳过类定义
如果不想定义多层类,可以直接反序列化为dynamic类型:
public async Task<dynamic> WeatherApiResult() { // 前面的请求逻辑不变 var responseContent = await httpResponse.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<dynamic>(responseContent); }
这种方式可以直接像JavaScript一样访问嵌套属性,缺点是没有编译时检查,属性名拼写错误只会在运行时报错。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

