Reputation: 1182
I have no previous experience with JSON or using web services, however I'm trying to consume a web service that returns meteorological information.
Here's the documentation on the API that I'm trying to use.
This API gives me data serialized with JSON. I did some reading into JSON, and from what I understand, the best way to access this serialized data after I download it would be to de-serialize it into an object with matching properties and types. Did I get this part right? I don't understand however in this case how am I supposed to accurately know the types of the data returned via JSON.
In the API that I mentioned before I got this example of a response from the API in JSON:
{"coord":
{"lon":145.77,"lat":-16.92},
"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],
"base":"cmc stations",
"main":{"temp":293.25,"pressure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37},
"wind":{"speed":5.1,"deg":150},
"clouds":{"all":75},
"rain":{"3h":3},
"dt":1435658272,
"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunrise":1435610796,"sunset":1435650870},
"id":2172797,
"name":"Cairns",
"cod":200}
What I did was, on Visual Studio I used the "Paste Special" > "Paste as JSON classes" option, which created these classes for me:
public class Rootobject
{
public Coord coord { get; set; }
public Weather[] weather { get; set; }
public string _base { get; set; }
public Main main { get; set; }
public Wind wind { get; set; }
public Clouds clouds { get; set; }
public Rain rain { get; set; }
public int dt { get; set; }
public Sys sys { get; set; }
public int id { get; set; }
public string name { get; set; }
public int cod { get; set; }
}
public class Coord
{
public float lon { get; set; }
public float lat { get; set; }
}
public class Main
{
public float temp { get; set; }
public int pressure { get; set; }
public int humidity { get; set; }
public float temp_min { get; set; }
public float temp_max { get; set; }
}
public class Wind
{
public float speed { get; set; }
public int deg { get; set; }
}
public class Clouds
{
public int all { get; set; }
}
public class Rain
{
public int _3h { get; set; }
}
public class Sys
{
public int type { get; set; }
public int id { get; set; }
public float message { get; set; }
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; }
}
The problem is that when I request data using the HttpClient, when I try to de-serialize the response I get I few errors regarding mismatching data types, like for example, float data being assign to properties of the type int.
Here's a snippet of my code:
string json = await client.GetStringAsync("weather?q=London,uk&appid=010101010101010101101");
Rootobject currentWeather = new Rootobject();
currentWeather = JsonConvert.DeserializeObject<Rootobject>(json);
MessageBox.Show(currentWeather.name);
I understand that in this case I could change the types of the properties in my classes to match what is being returned by the API, however that doesn't feel right to me, mainly because seems like it could be a source of troubles and unpredictable behavior. Am I doing this right? Maybe I'm missing something in the API documentation, shouldn't they provide the type of the data being returned?
Upvotes: 1
Views: 102
Reputation: 518
Correct : De-serialize it into an object with matching properties and types.
First check the API documentation for the types, and if that is not comprehensiive enough I would consider changing your types to match what you infer from the JSON.
A value of 289.9 is a float.
A value of 1435650870 can be stored an int.
A value of AU can be a string/enum.
Edit: I checked the API documentation you linked to and don't see anywhere were it explicitly states the types of data returned.
Edit 2: Answering your question more directly, "how am I supposed to accurately know the types of the data returned via JSON?" (thanks @CodeCaster), without finding that information in documentation I don't think you can.
But I feel you can get 99.999% close by just looking at historical data returned.
Upvotes: 2
Reputation: 96
If it is satisfied for you to use dynamic you can try this snippet
string json = await client.GetStringAsync("weather?q=London,uk&appid=010101010101010101101");
dynamic currentWeather= JObject.Parse(json);
MessageBox.Show(currentWeather.name);
You will find more details in documentation
Upvotes: 0