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.