Consuming JSON from a C# Project
November 20, 2012 17 Comments
I was thinking about an app that I have wanted to write for a while. Part of the application uses weather data. Since I have been using weather underground since forever (Go Blue), that seemed like a natural place to start. I hopped over to wunderground and sure enough, at the bottom of the page is a link for consuming its API.
Following the Weather API for Developers – JSON link, I signed up for a free developer account. Within minutes I got my API key and I was ready to start looking for the data I was interested in for my application. I first went to the documentation page, I started with the current conditions for a city example:
http://api.wunderground.com/api/axxxxxx/conditions/q/CA/San_Francisco.json
I then switched out the state/city criteria with my zip code:
http://api.wunderground.com/api/axxxxxxxx/conditions/q/27519.json
Sure enough, data is getting returned.
Now that I have a source of data, I need a way to consume the data using Visual Studio. I fired up a Console project just to see how difficult it would be to consume. I put in a typical webrequest/response:
Uri uri = new Uri(@"http://api.wunderground.com/api/xxxxxxxx/conditions/q/27519.json"); WebRequest webRequest = WebRequest.Create(uri); WebResponse response = webRequest.GetResponse(); StreamReader streamReader = new StreamReader(response.GetResponseStream()); String responseData = streamReader.ReadToEnd(); Console.WriteLine(responseData);
Sure enough, I am getting the data back:
The next step is to parse this string so I can do something useful with it. Fortunately, I was coding this solution during a meeting of Cary’s Technology Task Force and I was sitting next to an OData/JSON expert: Ian Cillay . Ian told me that to parse Json from VS, I needed to get Newtonsoft’s Json.NET framework because MSFT has essentially given up on the parsing and is deferring everything to NewtonSoft. Once I had that installed via NuGet, I the realized I still needed a class pre-defined to populate from the Json feed. I fired up a new class with a couple of properties:
public class WeatherData { public String pressue_mb { get; set; } public String pressume_in { get; set; } public String pressure_trend { get; set; } public String relative_humidity { get; set; } }
I then coded up line to use that Json library to put the data from the response string into an instantiated class:
var outObject = JsonConvert.DeserializeObject<WeatherData>(responseData);
However, when I ran it, nothing was getting populated.
Ian told me that my simple class did not reflect the actual Json. Stumped (and still hating Json), I then stumbled across this site. Sure enough it was like SVCUTIL.exe for Json. I got the classes created for me
and I then could consume the data like this:
var outObject = JsonConvert.DeserializeObject<RootObject>(responseData);
and the output is
Wahoo! I will use the Visual Studio’s External Tools Feature to generate classes for me on the fly:
Works great….
Thanks!
Thank you, thank you, thank you. I really didn’t want to write all of these classes by hand!
Thank you so much for sharing!
Worked perfectly.
This wouldn’t require you to make a proxy for every us city would it?
Sorry if I am asking a stupid question. I am trying to use wunderground to get its alerts for my weather app, which allows anyone in the us to get weather related alerts and basically get alerted about them so if there is a tornado spotted they can go and run and take cover before it affects them.
nope. 1 proxy.
Thank you so much for sharing!
Worked perfectly.
very well bro (y) worked perfect
You are a lifesaver!!!
Thanke You..!!! ALLAH RAZI OLSUN
oooooooooooooooooohhhhhhhhhhhhhh goodnesssssssssssss …..thank you man!!!!
No Bueno…
string URI = “http://api.wunderground.com/api/969c30d9979df192/conditions/q/OR/Roseburg.json”;
WebRequest weatherRequest = WebRequest.Create(URI);
WebResponse weatherResponse = weatherRequest.GetResponse();
StreamReader weatherStream = new StreamReader(weatherResponse.GetResponseStream());
string weatherString = weatherStream.ReadToEnd();
ProgLog.Log(weatherString, PROCNAME, MODNAME);
//WeatherContract weather = JsonConvert.DeserializeObject(weatherString);
CurrentObservation currentObservations = JsonConvert.DeserializeObject(weatherString);
All properties of currentObservations are BLANK or 0
What gives, Professor?
– Doug
Not seeing where you actually put the data from JSON into data classes.
When I attempt to parse into classes from deserilization object I need a data contract
OK,
No data contract but MUST “cast” desrialize result to RootObject like this…
var currentObservations = JsonConvert.DeserializeObject(weatherString);
Previous code sample should have read…
var currentObservations = JsonConvert.DeserializeObject(weatherString);
My copy paste skills are lacking. 😦
OK.
“var currentObservations = JsonConvert.DeserializeObject(weatherString);”
Why is site leaving out my cast to RootObject ???????
OK.
Got it working.
Very cool and very nice write up. Very clear – except for boneheads like me!