0

Error:

An unhandled exception occurred while processing the request. JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Project.Models.Hourly_Units]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'hourly_units.time', line 1, position 194.

About project: I am getting json data, mapping to model class. than using controller to get json data and displaying in View. I can get single values working in View but having issue displaying List<Hourly_Units> and List<Hourly>

Step#1 - json data

Step#2 - Model Class

public class WeatherModel
{
    public double latitude { get; set; }
    public double longitude { get; set; }
    public double generationtime_ms { get; set; }
    public double utc_offset_seconds { get; set; }
    public string timezone { get; set; }
    public string timezone_abbreviation { get; set; }
    public string elevation { get; set; }
    public List<Hourly_Units> hourly_units { get; set; }
    public List<Hourly> hourly { get; set; }
}

public class Hourly_Units
{
    public string time { get; set; }
    public string temperature_2m { get; set; }
}
public class Hourly
{
    public List<string> time { get; set; }
    public List<double> temperature_2m { get; set; }
}

Step#3 - Controller

    public async Task<IActionResult> Index()
    {
        //Weather API 
        WeatherModel MyWeatherData = new WeatherModel();
        MyWeatherData = await GetMyWeather();

        return View(MyWeatherData);
    }

    public async Task<WeatherModel> GetMyWeather()
    {
        var latitude = 40.712776;
        var longitude = -74.005974;

        using (var client = new HttpClient())
        {
            try
            {
                client.BaseAddress = new Uri("https://api.open-meteo.com");
                var response = await client.GetAsync($"/v1/forecast?latitude={latitude}&longitude={longitude}&hourly=temperature_2m");
                response.EnsureSuccessStatusCode();

                var stringResult = await response.Content.ReadAsStringAsync(); //get json data in string 
                var rawWeather = JsonConvert.DeserializeObject<WeatherModel>(stringResult); // convert json data into objects

                return rawWeather;

            }
            catch (HttpRequestException httpRequestException)
            {
                throw new Exception($"Error getting weather from OpenWeather: {httpRequestException.Message}");
            }
        }
    }//end of method 

Step#4 - View

@model WeatherModel

<form asp-controller="Home" asp-action="Index">
        <button type="submit" class="btn btn-primary">Submit</button>
</form>

<p>latitude: @Model.latitude</p>
<p>longitude: @Model.longitude</p>
<p>generationtime_ms: @Model.generationtime_ms</p>
<p>utc_offset_seconds: @Model.utc_offset_seconds</p>
<p>timezone: @Model.timezone</p>
<p>timezone_abbreviation: @Model.timezone_abbreviation</p>
<p>elevation: @Model.elevation</p>

<p>
    @foreach (var item in Model.hourly_units)
   {
        @Html.DisplayFor(modelItem => item.time)
        @Html.DisplayFor(modelItem => item.temperature_2m)
    }
</p>
<p>
    @foreach (var item in Model.hourly)
    {
        @Html.DisplayFor(modelItem => item.time)
        @Html.DisplayFor(modelItem => item.temperature_2m)
    }
</p>

1 Answer 1

2

Fix the model,you hourly_units property is not a collection, this is what is an error message about

public class WeatherModel
{
    //another properties
    public Hourly_Units hourly_units { get; set; }
    public List<Hourly> hourly { get; set; }
}

public class Hourly
{
    public string time { get; set; }
    public string temperature_2m { get; set; }
}

fix the action code, parse your json string and convert to the new data model

    var jObj = JObject.Parse(stringResult);

    var jArr = new JArray();
    for (int i = 0; i < ((JArray)jObj["hourly"]["time"]).Count; i++)
    {
        jArr.Add(new JObject
        {
            ["time"] = (string)((JArray)jObj["hourly"]["time"])[i],
            ["temperature_2m"] = (double)((JArray)jObj["hourly"]["temperature_2m"])[i]
        });
    }
    jObj["hourly"] = jArr;

    var rawWeather = jObj.ToObject<WeatherModel>();

and fix the view code according to the new model too.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.