Home > OS >  map json DeserializeObject into multi model class
map json DeserializeObject into multi model class

Time:01-20

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" >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>

CodePudding user response:

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.

  • Related