Answered by:
Parsing JSON with HttpClient

Question
-
Hi,
I'm attempting to port some code from my Windows Phone app to Windows 8, which parses JSON using HttpClient. It's not working out and I'd appreciate if someone can correct my code.
Note that I am unable to use Json.net for this code so I need the code to be exactly like the Windows Phone version in terms of functionality.
Windows 8
async void test_fetch() { var client = new HttpClient(); var uri = new Uri("http://ponify.me/stats.php"); var response = await client.GetAsync(uri); var serializer = new DataContractJsonSerializer(typeof(RootObject)); if (response.StatusCode != null) { if (response.StatusCode.Equals("NotFound")) { var messageDialog = new MessageDialog("Could not retrieve playlist", "Error"); messageDialog.Commands.Add(new UICommand("Close", (command) => { })); messageDialog.DefaultCommandIndex = 0; await messageDialog.ShowAsync(); } else { var messageDialog = new MessageDialog("Could not retrieve playlist", "Error"); messageDialog.Commands.Add(new UICommand("Close", (command) => { })); messageDialog.DefaultCommandIndex = 0; await messageDialog.ShowAsync(); } } else { var songHistory = (RootObject)serializer.ReadObject(response.Content); foreach (var obj in songHistory.SONGHISTORY.Take(1)) string cestfetch = obj.TITLE; var messageDialog = new MessageDialog(cestfetch, "Radio: Now Playing"); messageDialog.Commands.Add(new UICommand("Close", (command) => { })); messageDialog.DefaultCommandIndex = 0; await messageDialog.ShowAsync(); } }
public class RootObject
{
public int CURRENTLISTENERS { get; set; }
public int PEAKLISTENERS { get; set; }
public int MAXLISTENERS { get; set; }
public string SERVERURL { get; set; }
public string SERVERTITLE { get; set; }
public bool STREAMSTATUS { get; set; }
public int BITRATE { get; set; }
public int STREAM_START { get; set; }
public List<SONGHISTORY> SONGHISTORY { get; set; }
}
public class SONGHISTORY
{
public string PLAYEDAT { get; set; }
public string TITLE { get; set; }
public string ARTIST { get; set; }
public int? ARTISTID { get; set; }
public string SONG { get; set; }
public int? SONGID { get; set; }
}
Windows Phone
private void testPLB_Tap(object sender, System.Windows.Input.GestureEventArgs e) { testPLB.FontSize = 15; testPLB.Content = "Fetching..."; var client = new WebClient(); client.OpenReadCompleted += (s, eargs) => { var serializer = new DataContractJsonSerializer(typeof(RootObject)); if (eargs.Error != null) { if (eargs.Error.Message.Contains("NotFound")) { MessageBox.Show("Could not retrieve playlist", "Error", MessageBoxButton.OK); testPLB.Content = "Could not retrieve playlist"; } else { MessageBox.Show("Could not retrieve playlist", "Error", MessageBoxButton.OK); testPLB.Content = "Could not retrieve playlist"; } } else { var songHistory = (RootObject)serializer.ReadObject(eargs.Result); foreach (var obj in songHistory.SONGHISTORY.Take(1)) testPLB.Content = obj.TITLE; } }; var uri = new Uri("http://ponify.me/stats.php"); client.OpenReadAsync(uri); } public class RootObject { public int CURRENTLISTENERS { get; set; } public int PEAKLISTENERS { get; set; } public int MAXLISTENERS { get; set; } public string SERVERURL { get; set; } public string SERVERTITLE { get; set; } public bool STREAMSTATUS { get; set; } public int BITRATE { get; set; } public int STREAM_START { get; set; } public List<SONGHISTORY> SONGHISTORY { get; set; } } public class SONGHISTORY { public string PLAYEDAT { get; set; } public string TITLE { get; set; } public string ARTIST { get; set; } public int? ARTISTID { get; set; } public string SONG { get; set; } public int? SONGID { get; set; } }
Any help would be appreciated, thanks.
Saturday, January 12, 2013 5:21 PM
Answers
-
Hello.
Try using the DataContractJsonSerializer. In this example, your service is read and deserialized into an object called feed that is the type of your rootObject. From there, it should be easy to access any attribute. (Also see How to Serialize and Deserialize Json Data)
Note, that I changed the name of one of your classes to make it easier to distinguish between the array and the items in it.
private async void Button_Click_1(object sender, RoutedEventArgs e) { var client = new HttpClient(); var uri = new Uri("http://ponify.me/stats.php"); Stream respStream = await client.GetStreamAsync(uri); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(rootObject)); rootObject feed = (rootObject)ser.ReadObject(respStream); System.Diagnostics.Debug.WriteLine(feed.SONGHISTORY[0].TITLE); } } [DataContract] public class rootObject { [DataMember] public int CURRENTLISTENERS { get; set; } [DataMember] public int PEAKLISTENERS { get; set; } [DataMember] public int MAXLISTENERS { get; set; } [DataMember] public string SERVERURL { get; set; } [DataMember] public string SERVERTITLE { get; set; } [DataMember] public bool STREAMSTATUS { get; set; }
[DataMember] public int BITRATE { get; set; } [DataMember] public int STREAM_START { get; set; } [DataMember] public List<SongItem> SONGHISTORY { get; set; } } public class SongItem { public string PLAYEDAT { get; set; } public string TITLE { get; set; } public string ARTIST { get; set; } public int? ARTISTID { get; set; } public string SONG { get; set; } public int? SONGID { get; set; } }
- Marked as answer by ReignOfComputer Sunday, January 13, 2013 4:15 PM
- Edited by jrboddie Sunday, January 13, 2013 4:15 PM
Sunday, January 13, 2013 3:43 PM
All replies
-
try to use the JSON object provided with the .net 4.5 will find it in the namespace Windows.Data.Json
Example
var client = new HttpClient(); var uri = new Uri("http://ponify.me/stats.php"); var response = await client.GetStringAsync(uri); JsonObject parser = JsonObject.Parse(response); var STREAMSTATUS = parser["STREAMSTATUS"].GetBoolean();
- Proposed as answer by Ahmed-Fouad Saturday, January 12, 2013 11:41 PM
Saturday, January 12, 2013 11:41 PM -
Thanks for the reply.
I need the first entry for TITLE of SONGHISTORY in the Json, which is in a List. My code is currently:
var client = new HttpClient(); var uri = new Uri("http://ponify.me/stats.php"); var response = await client.GetStringAsync(uri); JsonObject parser = JsonObject.Parse(response); var SONGHISTORY = parser["SONGHISTORY"].GetArray(); System.Diagnostics.Debug.WriteLine(SONGHISTORY[1].ToString());
Where WriteLine outputs "Windows.Data.Json.JsonValue".
How would I proceed from here?
Sunday, January 13, 2013 6:03 AM -
Hello.
Try using the DataContractJsonSerializer. In this example, your service is read and deserialized into an object called feed that is the type of your rootObject. From there, it should be easy to access any attribute. (Also see How to Serialize and Deserialize Json Data)
Note, that I changed the name of one of your classes to make it easier to distinguish between the array and the items in it.
private async void Button_Click_1(object sender, RoutedEventArgs e) { var client = new HttpClient(); var uri = new Uri("http://ponify.me/stats.php"); Stream respStream = await client.GetStreamAsync(uri); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(rootObject)); rootObject feed = (rootObject)ser.ReadObject(respStream); System.Diagnostics.Debug.WriteLine(feed.SONGHISTORY[0].TITLE); } } [DataContract] public class rootObject { [DataMember] public int CURRENTLISTENERS { get; set; } [DataMember] public int PEAKLISTENERS { get; set; } [DataMember] public int MAXLISTENERS { get; set; } [DataMember] public string SERVERURL { get; set; } [DataMember] public string SERVERTITLE { get; set; } [DataMember] public bool STREAMSTATUS { get; set; }
[DataMember] public int BITRATE { get; set; } [DataMember] public int STREAM_START { get; set; } [DataMember] public List<SongItem> SONGHISTORY { get; set; } } public class SongItem { public string PLAYEDAT { get; set; } public string TITLE { get; set; } public string ARTIST { get; set; } public int? ARTISTID { get; set; } public string SONG { get; set; } public int? SONGID { get; set; } }
- Marked as answer by ReignOfComputer Sunday, January 13, 2013 4:15 PM
- Edited by jrboddie Sunday, January 13, 2013 4:15 PM
Sunday, January 13, 2013 3:43 PM -
That did it perfectly, thanks so much!Sunday, January 13, 2013 4:15 PM