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

使用C# GetFromJsonAsync反序列化JSON时无法获取子对象值

问题描述

使用C#的GetFromJsonAsync方法反序列化Open Meteo API返回的JSON时,能正常提取latitude、longitude等顶层字段,但无法获取current_weather子结构中的temperature、windspeed等值,当前代码中Temperature始终返回0,尝试创建current_weather对应的类但未成功。

示例JSON响应:

{
  "latitude": 38.4375,
  "longitude": 27.25,
  "generationtime_ms": 0.21195411682128906,
  "utc_offset_seconds": 0,
  "timezone": "GMT",
  "timezone_abbreviation": "GMT",
  "elevation": 137,
  "current_weather": {
    "temperature": 12.3,
    "windspeed": 6.4,
    "winddirection": 137,
    "weathercode": 3,
    "time": "2023-02-26T06:00"
  }
}

原代码:

using System.Net.Http.Json;
using System.Runtime.ConstrainedExecution;

namespace HttpClientExtensionMethods
{
    public class City
    {
        public float Latitude { get; set; }
        public float Longitude { get; set; }
        public float Temperature { get; set; }
    }
        
    public class Program
    {
        public static async Task Main()
        {
            using HttpClient client = new()
            {
                BaseAddress = new Uri("https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&current_weather=true")
            };

            // Get Json Weather information.
            City? city = await client.GetFromJsonAsync<City>("");
          
            Console.WriteLine($"Latitude: {city?.Latitude}");
            Console.WriteLine($"Longitude: {city?.Longitude}");
            Console.WriteLine($"Temperature: {city?.Temperature}");
        }
    }
}
解决方案

核心问题是类结构未与JSON的嵌套层级匹配:原City类中的Temperature属性尝试映射顶层字段,但JSON中temperature属于current_weather子对象,因此无法匹配,最终返回float类型的默认值0。

需要按以下步骤修改:

  1. 定义CurrentWeather类,对应JSON中的current_weather子结构:
    由于JSON使用蛇形命名,C#中建议用帕斯卡命名并通过JsonPropertyName特性映射到JSON键名,确保序列化/反序列化正确匹配。

  2. 修改City类,添加CurrentWeather类型的属性,同样用特性映射JSON键名。

  3. 更新输出逻辑,访问嵌套对象中的属性值。

修改后的完整代码:

using System.Net.Http.Json;
using System.Text.Json.Serialization;

namespace HttpClientExtensionMethods
{
    public class City
    {
        [JsonPropertyName("latitude")]
        public float Latitude { get; set; }

        [JsonPropertyName("longitude")]
        public float Longitude { get; set; }

        [JsonPropertyName("current_weather")]
        public CurrentWeather? CurrentWeather { get; set; }
    }

    public class CurrentWeather
    {
        [JsonPropertyName("temperature")]
        public float Temperature { get; set; }

        [JsonPropertyName("windspeed")]
        public float WindSpeed { get; set; }

        [JsonPropertyName("winddirection")]
        public int WindDirection { get; set; }

        [JsonPropertyName("weathercode")]
        public int WeatherCode { get; set; }

        [JsonPropertyName("time")]
        public DateTime Time { get; set; }
    }
        
    public class Program
    {
        public static async Task Main()
        {
            using HttpClient client = new()
            {
                BaseAddress = new Uri("https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&current_weather=true")
            };

            City? city = await client.GetFromJsonAsync<City>("");
          
            Console.WriteLine($"Latitude: {city?.Latitude}");
            Console.WriteLine($"Longitude: {city?.Longitude}");
            Console.WriteLine($"Temperature: {city?.CurrentWeather?.Temperature}");
            Console.WriteLine($"Wind Speed: {city?.CurrentWeather?.WindSpeed}");
        }
    }
}
关键说明
  • 使用JsonPropertyName特性确保C#类属性与JSON键名严格匹配,避免因命名风格差异导致映射失败。
  • 嵌套对象属性需声明为可空类型(如CurrentWeather?),防止JSON中该字段缺失时引发空引用异常。
  • 若不需要所有子字段,可只保留CurrentWeather类中需要的属性(如仅Temperature),反序列化时会自动忽略未定义的字段。

内容的提问来源于stack exchange,提问作者PairMem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:55:12