Parsing Open Weather Map API response fails [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have this snippet of code:
public void getForcast()
{
string url = string.Format("https://samples.openweathermap.org/data/2.5/weather?q=London&appid=b6907d289e10d714a6e88b30761fae22");
using (WebClient web = new WebClient())
{
var json = web.DownloadString(url);
var obj = JsonConvert.DeserializeObject<WeatherData.WeatherForcast>(json);
WeatherData.WeatherForcast forcast = obj;
WeatherMark.Text = string.Format("{0}", forcast.list[1].weathers[0].description);
}
}
I want it to get description of it from forecast list.
But instead I'm getting this error
Object reference not set to an instance of an object
here's my whole list of classes:
class WeatherForcast
{
public List<list> list { get; set; }
}
public class weather
{
public string main { get; set; }
public string description { get; set; }
}
public class list
{
public List<weather> weathers { get; set; }
}
anyone knows why does it appear?

The JSON most likely does not match the provided class definition which results in a null object when parsed.
Calling the shown URL in a browser provides the following JSON response
{"coord":{"lon":-0.13,"lat":51.51},"weather":[{"id":300,"main":"Drizzle","description":"light
intensity
drizzle","icon":"09d"}],"base":"stations","main":{"temp":280.32,"pressure":1012,"humidity":81,"temp_min":279.15,"temp_max":281.15},"visibility":10000,"wind":{"speed":4.1,"deg":80},"clouds":{"all":90},"dt":1485789600,"sys":{"type":1,"id":5091,"message":0.0103,"country":"GB","sunrise":1485762037,"sunset":1485794875},"id":2643743,"name":"London","cod":200}
Which can be mapped to your shown code already provided with some modification.
public class WeatherForcast {
public List<weather> weather { get; set; }
}
public class weather {
public string main { get; set; }
public string description { get; set; }
}
There are online tools available where you can place the JSON and it will generate the mapped classes for the JSON.

You can get weather in Xml using &mode=xml and then use xml serialization :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string URL = "https://samples.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid=b6907d289e10d714a6e88b30761fae22";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(URL);
XmlSerializer serializer = new XmlSerializer(typeof(Weather));
Weather weather = (Weather)serializer.Deserialize(reader);
}
}
[XmlRoot("current")]
public class Weather
{
public City city { get; set; }
public Temperature temperature { get; set; }
public Humidity humidity { get; set; }
public Pressure pressure { get; set; }
public Wind wind { get; set; }
}
public class City
{
[XmlAttribute()]
public string name { get; set; }
[XmlAttribute()]
public string id { get; set; }
public Coord coord { get; set; }
public string country { get; set; }
public Sun sun { get; set; }
}
public class Sun
{
[XmlAttribute()]
public DateTime rise { get; set; }
[XmlAttribute()]
public DateTime set { get; set; }
}
public class Coord
{
[XmlAttribute()]
public decimal lon { get; set; }
[XmlAttribute()]
public decimal lat { get; set; }
}
public class Temperature
{
[XmlAttribute()]
public decimal value { get; set; }
[XmlAttribute()]
public decimal min { get; set; }
[XmlAttribute()]
public decimal max { get; set; }
}
public class Humidity
{
[XmlAttribute()]
public decimal value { get; set; }
}
public class Pressure
{
[XmlAttribute()]
public decimal value { get; set; }
}
public class Wind
{
public Speed speed { get; set; }
public Direction direction { get; set; }
}
public class Speed
{
[XmlAttribute()]
public decimal value { get; set; }
[XmlAttribute()]
public string name { get; set; }
}
public class Direction
{
[XmlAttribute()]
public decimal value { get; set; }
[XmlAttribute()]
public string name { get; set; }
[XmlAttribute()]
public string code { get; set; }
}
}

Related

How to deserialize a string containing multiple JSON [duplicate]

This question already has answers here:
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value
(2 answers)
Closed 7 months ago.
From time to time, my system, through a Timer, executes a procedure that captures a list of events generated by the API, however, when trying to serialize, it returns the following error.
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: {. Path '[1].metadata', line 1, position 453.'
In this case, this is the string I get from the API.
[{"id":"6ed69e14-6610-4b57-a06f-328f38a9e2aa","code":"PLC","fullCode":"PLACED","orderId":"c6184662-2116-4a66-9f6b-4e6caca59e0d","merchantId":"355d10e6-8825-46e3-81dc-0961bf27a5dc","createdAt":"2022-07-14T12:45:34.142Z"},{"id":"e064302e-6a65-4821-ba4c-ea7021aaf8cc","code":"CAN","fullCode":"CANCELLED","orderId":"c6184662-2116-4a66-9f6b-4e6caca59e0d","merchantId":"355d10e6-8825-46e3-81dc-0961bf27a5dc","createdAt":"2022-07-14T12:53:34.674Z","metadata":{"CANCEL_STAGE":"[PRE_CONFIRMED]","ORIGIN":"IfoodGatewayAgent","CANCEL_CODE":"902","CANCELLATION_DISPUTE":{"IS_CONTESTABLE":"CANCELLATION_IS_NOT_CONTESTABLE","REASON":"NO_CREDIT_FOR_ORDER_LIABILITIES"},"CANCELLATION_OCCURRENCE":{"tags":["NO_CREDIT_FOR_ORDER_LIABILITIES"],"RESTAURANT":{"FINANCIAL_OCCURRENCE":"NA","PAYMENT_TYPE":"NA"},"CONSUMER":{"FINANCIAL_OCCURRENCE":"NA","PAYMENT_TYPE":"NA"},"LOGISTIC":{"FINANCIAL_OCCURRENCE":"NA","PAYMENT_TYPE":"NA"}},"TIMEOUT_EVENT":false,"CANCEL_ORIGIN":"RESTAURANT","CANCEL_REASON":"AUTOMATICO - NAO CONFIRMADO PELO RESTAURANTE","CANCEL_USER":"Order BackOffice Scheduler","CANCELLATION_REQUESTED_EVENT_ID":"17da3940-661e-4d9c-a15a-57f5d1b06474"}}]
This is the part that gives an error in the code:
var data = response.Content.ReadAsStringAsync();
var bodyResponse = JsonConvert.DeserializeObject<List<Classes.OrderStatus>>(await data);
Class OrderStatus:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SAFI_Delivery.Classes
{
internal class OrderStatus
{
[JsonProperty("id")]
public string ID { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("fullCode")]
public string FullCode { get; set; }
[JsonProperty("orderId")]
public string OrderID { get; set; }
[JsonProperty("merchantId")]
public string MerchantID { get; set; }
[JsonProperty("createdAt")]
public string CreatedAt { get; set; }
[JsonProperty("metadata")]
public string Metadata { get; set; }
}
}
I would like to know how I make it consider that this is a list and not a string?
you have to fix classes and code
var json= await response.Content.ReadAsStringAsync();
var bodyResponse = JsonConvert.DeserializeObject<List<OrderStatus>>(json);
classes
public partial class OrderStatus
{
[JsonProperty("id")]
public Guid Id { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("fullCode")]
public string FullCode { get; set; }
[JsonProperty("orderId")]
public Guid OrderId { get; set; }
[JsonProperty("merchantId")]
public Guid MerchantId { get; set; }
[JsonProperty("createdAt")]
public DateTimeOffset CreatedAt { get; set; }
[JsonProperty("metadata", NullValueHandling = NullValueHandling.Ignore)]
public Metadata Metadata { get; set; }
}
public partial class Metadata
{
[JsonProperty("CANCEL_STAGE")]
public string CancelStage { get; set; }
[JsonProperty("ORIGIN")]
public string Origin { get; set; }
[JsonProperty("CANCEL_CODE")]
public long CancelCode { get; set; }
[JsonProperty("CANCELLATION_DISPUTE")]
public CancellationDispute CancellationDispute { get; set; }
[JsonProperty("CANCELLATION_OCCURRENCE")]
public CancellationOccurrence CancellationOccurrence { get; set; }
[JsonProperty("TIMEOUT_EVENT")]
public bool TimeoutEvent { get; set; }
[JsonProperty("CANCEL_ORIGIN")]
public string CancelOrigin { get; set; }
[JsonProperty("CANCEL_REASON")]
public string CancelReason { get; set; }
[JsonProperty("CANCEL_USER")]
public string CancelUser { get; set; }
[JsonProperty("CANCELLATION_REQUESTED_EVENT_ID")]
public Guid CancellationRequestedEventId { get; set; }
}
public partial class CancellationDispute
{
[JsonProperty("IS_CONTESTABLE")]
public string IsContestable { get; set; }
[JsonProperty("REASON")]
public string Reason { get; set; }
}
public partial class CancellationOccurrence
{
[JsonProperty("tags")]
public List<string> Tags { get; set; }
[JsonProperty("RESTAURANT")]
public Consumer Restaurant { get; set; }
[JsonProperty("CONSUMER")]
public Consumer Consumer { get; set; }
[JsonProperty("LOGISTIC")]
public Consumer Logistic { get; set; }
}
public partial class Consumer
{
[JsonProperty("FINANCIAL_OCCURRENCE")]
public string FinancialOccurrence { get; set; }
[JsonProperty("PAYMENT_TYPE")]
public string PaymentType { get; set; }
}
Answered Question.
Thanks, Drew
I'm not too familiar with the JSON library you're using, but I suspect the issue is that, in your OrderStatus class, you have the Metadata property as a string type, but in your example JSON, the "metadata" key has an object value, not a string value.

Geocoding REST call C# Parsing JSON

I'm struggling to pick up the data returned from the Geocoding REST call below (I've removed my app_id and app_code so you cannot run the url as it is below):
https://geocoder.api.here.com/6.2/geocode.json?app_id=[MY APP ID]&app_code=[MY APP CODE]&searchtext=chester
An example reponse can be found here:
https://developer.here.com/documentation/geocoder/topics/quick-start-geocode.html
I know it returns results but I cannot seem to get the results through to my C# application, I don't know if I'm building the class system incorrectly or whether there's something else I'm doing wrong. I've built an application reading the places api with no problem before but this one seems different somehow.
The call returns with a status of OK:
public void GeoCode()
{
// BUILD INITIAL STRING BASED ON PARAMETERS
string url = "https://geocoder.api.here.com/6.2/geocode.json?app_id=gpZ1Ym7rwuXs6Xj1TsD8&app_code=4UXmaGFTe30LttFgOY7iqQ&searchtext=" + tbLoc.text;
// RUN THE ASYNCRONOUS COMMAND (I THINK)
StartCoroutine(GetText(url));
}
IEnumerator GetText(string url)
{
// CREATE WEB REQUEST WITH SPECIFIED URL
UnityWebRequest www = UnityWebRequest.Get(url);
// RETURN RESULTS FROM ASYNC COMMAND
yield return www.SendWebRequest();
// PARSE JSON RESPONSE
RootObject RootObject = JsonUtility.FromJson<RootObject>(www.downloadHandler.text);
// IF 200 (STATUS OKAY) GATHER RESULTS, ELSE RETURN ERROR
if (www.responseCode == 200)
{
BuildArray(RootObject);
}
else
{
Debug.Log("Call Failed With Error: " + www.responseCode.ToString());
}
}
private void BuildArray(RootObject RootObject)
{
print(RootObject.Response.View[0].Result[0].Location.Address.Label);
}
It attempts to run the BuildArray function but this returns a null reference. (I'm just using the NextPageInformation as the most basic option to test)
Below is the class structure I have built to deal with the JSON:
public class Address
{
public string Label { get; set; }
}
public class Location
{
public Address Address { get; set; }
}
public class Result
{
public Location Location { get; set; }
}
public class View
{
public List<Result> Result { get; set; }
}
public class Response
{
public List<View> View { get; set; }
}
public class RootObject
{
public Response Response { get; set; }
}
Can someone please help?
Thank you
If you want to parse only one key value pair from json then creating class structure will tedious job for you.
Instead of creating class structure you can Querying a json with Newtonsoft.
Parse your json.
Querying your parsed json to retrieve Label
value.
//1
JToken jToken = JToken.Parse(jsonString);
//2
string label = jToken["Response"]["View"][0]["Result"][0]["Location"]["Address"]["Label"].ToObject<string>();
Console.WriteLine(label);
Console.ReadLine();
Output: (from your sample json provided in link)
Note: You need to install newtonsoft.json package from nuget and add below namespace to your program.
using Newtonsoft.Json.Linq;
Edit:
If you want parsed your full json then first create a class structure like below
public class MetaInfo
{
public DateTime Timestamp { get; set; }
}
public class MatchQuality
{
public int City { get; set; }
public List<double> Street { get; set; }
public int HouseNumber { get; set; }
}
public class DisplayPosition
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class NavigationPosition
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class TopLeft
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class BottomRight
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class MapView
{
public TopLeft TopLeft { get; set; }
public BottomRight BottomRight { get; set; }
}
public class AdditionalData
{
public string value { get; set; }
public string key { get; set; }
}
public class Address
{
public string Label { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string County { get; set; }
public string City { get; set; }
public string District { get; set; }
public string Street { get; set; }
public string HouseNumber { get; set; }
public string PostalCode { get; set; }
public List<AdditionalData> AdditionalData { get; set; }
}
public class Location
{
public string LocationId { get; set; }
public string LocationType { get; set; }
public DisplayPosition DisplayPosition { get; set; }
public List<NavigationPosition> NavigationPosition { get; set; }
public MapView MapView { get; set; }
public Address Address { get; set; }
}
public class Result
{
public int Relevance { get; set; }
public string MatchLevel { get; set; }
public MatchQuality MatchQuality { get; set; }
public string MatchType { get; set; }
public Location Location { get; set; }
}
public class View
{
public string _type { get; set; }
public int ViewId { get; set; }
public List<Result> Result { get; set; }
}
public class Response
{
public MetaInfo MetaInfo { get; set; }
public List<View> View { get; set; }
}
public class RootObject
{
public Response Response { get; set; }
}
And then you can deserialized your json like.
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
Note: You need to add below namespace to your program.
using Newtonsoft.Json;
I personally had problems parsing nested json objects with JsonUtility. So I switched to Newtonsoft Json and it works really well.
In your case you need to mark the classes as serialized using [Serializable] see here
[Serializable]
public class Address
{
public string Label;
}

Nested JSON failed to deserialize

This is the link for my nested JSON
: -
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=1500&type=restaurant&keyword=cruise&key=AIzaSyDk8ZfHO__XrYfDGi9RnFA_WxlVmRW5HMI
i have generated a model class which has to give me the list of names , later i populate them in a RecyclerView.
using System;
using System.Collections.Generic;
namespace newApp.Model
{
public class Location
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Northeast
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Southwest
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Viewport
{
public Northeast northeast { get; set; }
public Southwest southwest { get; set; }
}
public class Geometry
{
public Location location { get; set; }
public Viewport viewport { get; set; }
}
public class OpeningHours
{
public bool open_now { get; set; }
}
public class Photo
{
public int height { get; set; }
public List<string> html_attributions { get; set; }
public string photo_reference { get; set; }
public int width { get; set; }
}
public class PlusCode
{
public string compound_code { get; set; }
public string global_code { get; set; }
}
public class Result
{
public Geometry geometry { get; set; }
public string icon { get; set; }
public string id { get; set; }
public string name { get; set; }
public OpeningHours opening_hours { get; set; }
public List<Photo> photos { get; set; }
public string place_id { get; set; }
public PlusCode plus_code { get; set; }
public double rating { get; set; }
public string reference { get; set; }
public string scope { get; set; }
public List<string> types { get; set; }
public string vicinity { get; set; }
}
public class RootObject
{
public List<object> html_attributions { get; set; }
public List<Result> results { get; set; }
public string status { get; set; }
}
}
Then , in this method i tried to deserialize the data , i want to get a list of icon, name , id and location.
This is the method i initially have :
public async void getData()
{
var content = await _client.GetStringAsync(URL);
var n = JsonConvert.DeserializeObject<List<List<Result>>>(content);
Debug.WriteLine("Output ", n);
}
Try to deserialize to the RootObject class directly:
JsonConvert.DeserializeObject<RootObject>(content);
And then retrieve all data you need using LINQ.
Declare ResultHeadInfo class which will contain fields you need:
public class ResultHeadInfo
{
public Location Location { get; set; }
public string Name { get; set; }
public string Id { get; set; }
public string Icon { get; set; }
}
Then write LINQ query to get data:
var root = JsonConvert.DeserializeObject<RootObject>(content);
List<ResultHeadInfo> infoList = root.results.Select(x => new ResultHeadInfo {
Location = x.geometry.location,
Name = x.name,
Id = x.id,
Icon = x.icon
}).ToList();
By the way, you can use just Location object instead of Northest and Southwest as they are identical.
public class Viewport
{
public Location northeast { get; set; }
public Location southwest { get; set; }
}
In addition to the other answer, don't forget you can use attributes to identify the fields but keep the property names consistent with the usual naming conventions:
public partial class Viewport
{
[JsonProperty("northeast")]
public Location Northeast { get; set; }
[JsonProperty("southwest")]
public Location Southwest { get; set; }
}
I created those same classes recently for my project, and used quicktype.io to generate them. Much better output than the usual 'Paste Special' built into VS.

How to get data from JSON and convert into the object? [duplicate]

This question already has answers here:
Deserializing JSON data to C# using JSON.NET
(7 answers)
Closed 5 years ago.
I'm trying to receive data from request response which is JSON like this:
{
"cnt":1,
"list":[{
"coord":{
"lon":18.55,
"lat":50.11
},
"sys":{
"type":1,
"id":5356,
"message":0.0095,
"country":"PL",
"sunrise":1496630290,
"sunset":1496688673
},
"weather":[{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"01d"
}],
"main":{
"temp":293.71,
"pressure":1014,
"humidity":42,
"temp_min":293.15,
"temp_max":294.15
},
"visibility":10000,
"wind":{
"speed":4.1,
"deg":60
},
"clouds":{
"all":0
},
"dt":1496686603,
"id":7531758,
"name":"Rybnik"
}]
}
I'm trying to use JSON.NET to deserialize JSON and receive data. But I don't know exactly how to do it properly.
I tried to achieve this by using my class method:
public Rootobject DeserializeJSON()
{
private JObject responseObject;
private JToken responseToken;
private JArray responseArray;
responseObject = JObject.Parse(json);
Rootobject Weather = new Rootobject();
responseArray = (JArray)responseObject.SelectToken("list");
responseToken = (JToken)responseArray.SelectToken("main");
Weather = responseToken.ToObject<Rootobject>();
return Weather;
}
But It doesn't seems to work. In this case, I tried to receive data from "main" property in JSON and convert in to my class object:
class Main
{
public float temp { get; set; }
public float pressure { get; set; }
public float humidity { get; set; }
public float temp_min { get; set; }
public float temp_max { get; set; }
}
Could you explain me, how it should works and where's my fault, please?
Initially, you need to declare the following classes:
public class Coord
{
[JsonProperty("lon")]
public double Lon { get; set; }
[JsonProperty("lat")]
public double Lat { get; set; }
}
public class Sys
{
[JsonProperty("type")]
public int Type { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("message")]
public double Message { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("sunrise")]
public int Sunrise { get; set; }
[JsonProperty("sunset")]
public int Sunset { get; set; }
}
public class Weather
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("main")]
public string Main { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("icon")]
public string Icon { get; set; }
}
public class Main
{
[JsonProperty("temp")]
public double Temp { get; set; }
[JsonProperty("pressure")]
public int Pressure { get; set; }
[JsonProperty("humidity")]
public int Humidity { get; set; }
[JsonProperty("temp_min")]
public double TempMin { get; set; }
[JsonProperty("temp_max")]
public double TempMax { get; set; }
}
public class Wind
{
[JsonProperty("speed")]
public double Speed { get; set; }
[JsonProperty("deg")]
public int Deg { get; set; }
}
public class Clouds
{
[JsonProperty("all")]
public int All { get; set; }
}
public class List
{
[JsonProperty("coord")]
public Coord Coord { get; set; }
[JsonProperty("sys")]
public Sys Sys { get; set; }
[JsonProperty("weather")]
public IList<Weather> Weather { get; set; }
[JsonProperty("main")]
public Main Main { get; set; }
[JsonProperty("visibility")]
public int Visibility { get; set; }
[JsonProperty("wind")]
public Wind Wind { get; set; }
[JsonProperty("clouds")]
public Clouds Clouds { get; set; }
[JsonProperty("dt")]
public int Dt { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
public class Example
{
[JsonProperty("cnt")]
public int Cnt { get; set; }
[JsonProperty("list")]
public IList<List> List { get; set; }
}
Then you can deserialize your json as below:
var example = JsonConvert.DeserializeObject<Example>(jsonString)
where jsonString is your JSON.
PS. I derived the above classes using jsonutils and your json string.

get data from json c#

I have a problem I want to get data from Json, and the data
successfully gets from the json to the variable json but when I want to send the data to WeatherData it send me a zero value.
I have one class that cald "WeatherData" and I want to send to data from the json (that existing a class "jsonParse") to this class.
jsonParse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Web.Script.Serialization;
using System.IO;
namespace weather
{
public class jsonParse : Ijson
{
private string urlAdd;
public jsonParse(string _url)
{
if (_url == null)
{
//throw exption
}
else
urlAdd = _url;
}
public WeatherData parse()
{
//string json = new WebClient().DownloadString(urlAdd);
//var obj = JsonConvert.DeserializeObject<WeatherData>(json);
//Console.WriteLine(obj.temp);
// WeatherData m = JsonConvert.DeserializeObject<WeatherData>(json);
WebClient n = new WebClient();
var json = n.DownloadString(urlAdd);
string valueOriginal = Convert.ToString(json);
WeatherData m = JsonConvert.DeserializeObject<WeatherData>(json);
Console.WriteLine(m);
return m;
}
}
}
WeatherData
namespace weather
{
public class WeatherData
{
public WeatherData(double _temp, double _minTemp, double _maxTemp )
{
temp = _temp;
minTemp = _minTemp;
maxTemp = _maxTemp;
}
public double temp { get; set; }
public double minTemp { get; set; }
public double maxTemp { get; set; }
public override string ToString()
{
return "the weather:" + temp + "minTemp is:" + minTemp + "maxTemp:" + maxTemp;
}
}
}
json
{"coord":{"lon":139,"lat":35},
"sys":{"country":"JP","sunrise":1369769524,"sunset":1369821049},
"weather":[{"id":804,"main":"clouds","description":"overcast clouds","icon":"04n"}],
"main":{"temp":289.5,"humidity":89,"pressure":1013,"temp_min":287.04,"temp_max":292.04},
"wind":{"speed":7.31,"deg":187.002},
"rain":{"3h":0},
"clouds":{"all":92},
"dt":1369824698,
"id":1851632,
"name":"Shuzenji",
"cod":200}
If you only care about the weather part of the json, try this -
var o = (JArray)JObject.Parse(jsonString)["weather"];
foreach(JToken item in o)
{
Console.WriteLine(((JValue)item["id"]).Value);
Console.WriteLine(((JValue)item["main"]).Value);
Console.WriteLine(((JValue)item["description"]).Value);
Console.WriteLine(((JValue)item["icon"]).Value);
}
First object in json is coord, don't see that in your model.
You should change your JsonModel to deserialize. From c# class generator:
public class Coord
{
public int lon { get; set; }
public int lat { get; set; }
}
public class Sys
{
public string country { get; set; }
public int sunrise { get; set; }
public int sunset { get; set; }
}
public class Weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class Main
{
public double temp { get; set; }
public int humidity { get; set; }
public int pressure { get; set; }
public double temp_min { get; set; }
public double temp_max { get; set; }
}
public class Wind
{
public double speed { get; set; }
public double deg { get; set; }
}
public class Rain
{
public int __invalid_name__3h { get; set; }
}
public class Clouds
{
public int all { get; set; }
}
public class RootObject
{
public Coord coord { get; set; }
public Sys sys { get; set; }
public List<Weather> weather { get; set; }
public Main main { get; set; }
public Wind wind { get; set; }
public Rain rain { get; set; }
public Clouds clouds { get; set; }
public int dt { get; set; }
public int id { get; set; }
public string name { get; set; }
public int cod { get; set; }
}
Where RootObject is your JsonConvert.DeserializeObject(json);
So you can change class names as you like.
Simply you cannot Deserialize a json object to a non-matching class object. So make sure you have a model object that have atleast all the properties that JSON object have.
In this case you would need following classes that are generated from your JSON object:
public class Coord
{
public int lon { get; set; }
public int lat { get; set; }
}
public class Sys
{
public string country { get; set; }
public int sunrise { get; set; }
public int sunset { get; set; }
}
public class Weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class Main
{
public double temp { get; set; }
public int humidity { get; set; }
public int pressure { get; set; }
public double temp_min { get; set; }
public double temp_max { get; set; }
}
public class Wind
{
public double speed { get; set; }
public double deg { get; set; }
}
public class Rain
{
public int __invalid_name__3h { get; set; }
}
public class Clouds
{
public int all { get; set; }
}
public class ParentModel
{
public Coord coord { get; set; }
public Sys sys { get; set; }
public List<Weather> weather { get; set; }
public Main main { get; set; }
public Wind wind { get; set; }
public Rain rain { get; set; }
public Clouds clouds { get; set; }
public int dt { get; set; }
public int id { get; set; }
public string name { get; set; }
public int cod { get; set; }
}
ParentModel m = JsonConvert.DeserializeObject<ParentModel>(json);
Hope this helps.

Categories

Resources