You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 15:09:01