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

C#中如何从Dynamic对象获取Forecast节点的JSON数据值?

Fixing Dynamic Date Key Access in the Forecast Node (C# + Newtonsoft.Json)

Hey, let's sort out this issue you're having with accessing the dynamic date-based keys in the forecast node. I see you've tried splitting deserialization into two steps with dynamic, but couldn't pull values from it—let's walk through both a clean, type-safe solution (my recommendation) and how to make your existing approach work.

Option 1: Adjust Your Model for Direct Deserialization (Best Practice)

Instead of deserializing twice, we can update your Weather model to use a Dictionary<string, ForecastDay> for the Forecast property. Newtonsoft.Json will automatically map those dynamic date keys to the dictionary's keys, and the values to your ForecastDay object.

First, here's the complete set of model classes (with proper JSON property mapping if you prefer PascalCase for C# properties):

public class Weather
{
    public Request Request { get; set; }
    public Location Location { get; set; }
    public Current Current { get; set; }
    // Use Dictionary to handle dynamic date keys
    public Dictionary<string, ForecastDay> Forecast { get; set; }
}

public class Request
{
    [JsonProperty("type")]
    public string Type { get; set; }
    [JsonProperty("query")]
    public string Query { get; set; }
    [JsonProperty("language")]
    public string Language { get; set; }
    [JsonProperty("unit")]
    public string Unit { get; set; }
}

public class Location
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("country")]
    public string Country { get; set; }
    [JsonProperty("region")]
    public string Region { get; set; }
    [JsonProperty("lat")]
    public string Lat { get; set; }
    [JsonProperty("lon")]
    public string Lon { get; set; }
    [JsonProperty("timezone_id")]
    public string TimezoneId { get; set; }
    [JsonProperty("localtime")]
    public string LocalTime { get; set; }
    [JsonProperty("localtime_epoch")]
    public int LocalTimeEpoch { get; set; }
    [JsonProperty("utc_offset")]
    public string UtcOffset { get; set; }
}

public class Current
{
    [JsonProperty("observation_time")]
    public string ObservationTime { get; set; }
    [JsonProperty("temperature")]
    public int Temperature { get; set; }
    [JsonProperty("weather_code")]
    public int WeatherCode { get; set; }
    [JsonProperty("weather_icons")]
    public List<string> WeatherIcons { get; set; }
    [JsonProperty("weather_descriptions")]
    public List<string> WeatherDescriptions { get; set; }
    [JsonProperty("wind_speed")]
    public int WindSpeed { get; set; }
    [JsonProperty("wind_degree")]
    public int WindDegree { get; set; }
    [JsonProperty("wind_dir")]
    public string WindDir { get; set; }
    [JsonProperty("pressure")]
    public int Pressure { get; set; }
    [JsonProperty("precip")]
    public int Precip { get; set; }
    [JsonProperty("humidity")]
    public int Humidity { get; set; }
    [JsonProperty("cloudcover")]
    public int Cloudcover { get; set; }
    [JsonProperty("feelslike")]
    public int FeelsLike { get; set; }
    [JsonProperty("uv_index")]
    public int UvIndex { get; set; }
    [JsonProperty("visibility")]
    public int Visibility { get; set; }
    [JsonProperty("is_day")]
    public string IsDay { get; set; }
}

public class ForecastDay
{
    [JsonProperty("date")]
    public string Date { get; set; }
    [JsonProperty("date_epoch")]
    public int DateEpoch { get; set; }
    [JsonProperty("astro")]
    public Astro Astro { get; set; }
    [JsonProperty("mintemp")]
    public int MinTemp { get; set; }
    [JsonProperty("maxtemp")]
    public int MaxTemp { get; set; }
    [JsonProperty("avgtemp")]
    public int AvgTemp { get; set; }
    [JsonProperty("totalsnow")]
    public int TotalSnow { get; set; }
    [JsonProperty("sunhour")]
    public double SunHour { get; set; }
    [JsonProperty("uv_index")]
    public int UvIndex { get; set; }
}

public class Astro
{
    [JsonProperty("sunrise")]
    public string Sunrise { get; set; }
    [JsonProperty("sunset")]
    public string Sunset { get; set; }
    [JsonProperty("moonrise")]
    public string Moonrise { get; set; }
    [JsonProperty("moonset")]
    public string Moonset { get; set; }
    [JsonProperty("moon_phase")]
    public string MoonPhase { get; set; }
    [JsonProperty("moon_illumination")]
    public int MoonIllumination { get; set; }
}

Now you can deserialize once and access all data easily—including the forecast dates:

var weatherData = JsonConvert.DeserializeObject<Weather>(customerJsonString);

// Iterate through all forecast days
foreach (var dayKvp in weatherData.Forecast)
{
    string date = dayKvp.Key; // e.g., "2020-05-28"
    ForecastDay dayData = dayKvp.Value;
    
    Console.WriteLine($"Date: {date}");
    Console.WriteLine($"Max Temp: {dayData.MaxTemp}°C");
    Console.WriteLine($"Sunrise: {dayData.Astro.Sunrise}");
}

// Or get a specific day directly if you know the date
if (weatherData.Forecast.TryGetValue("2020-05-28", out ForecastDay specificDay))
{
    Console.WriteLine($"Average Temp on 2020-05-28: {specificDay.AvgTemp}");
}

This approach is type-safe, avoids dynamic pitfalls, and keeps your code clean.

Option 2: Make Your Existing Dynamic/Dictionary Approach Work

If you don't want to adjust your model right now, you can fix your current code to access values correctly. The key thing to remember is that JSON property names are case-sensitive here—you need to match the exact lowercase keys from your JSON.

Here's how to pull values from your forecast_details dynamic object:

var dataObjects23 = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(customerJsonString);
dynamic forecast_details = dataObjects23["forecast"];

// Option A: Loop through all forecast days
foreach (var forecastEntry in forecast_details)
{
    string dateKey = forecastEntry.Key;
    dynamic dayData = forecastEntry.Value;
    
    // Access properties using exact JSON names (lowercase)
    int maxTemp = dayData.maxtemp;
    string sunrise = dayData.astro.sunrise;
    
    Console.WriteLine($"Date: {dateKey}, Max Temp: {maxTemp}, Sunrise: {sunrise}");
}

// Option B: Get a specific day's data directly
dynamic targetDay = forecast_details["2020-05-28"];
int avgTemp = targetDay.avgtemp;
string moonPhase = targetDay.astro.moon_phase;

Console.WriteLine($"Avg Temp: {avgTemp}, Moon Phase: {moonPhase}");

Common Pitfalls to Check

If you're still not getting values with dynamic, double-check these:

  • Case sensitivity: JSON keys are lowercase (e.g., maxtemp), so don't use MaxTemp in your dynamic access.
  • JSON validity: Ensure the forecast node actually contains the date key you're trying to access—no typos in the date string.
  • Serialization settings: If you've modified JsonSerializerSettings (like a custom contract resolver), it might be altering how keys are mapped.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:02:39