How to parse Riot Games API response - c#

I am trying to make a simple app with Xamarin and the Riot Games API. I have trouble accessing summoner information. It works only with my username due to the way that my deserialization is done I think.
This is my code:
public async void GetSummonerInformation()
{
using (var client = new HttpClient())
{
var result = await client.GetStringAsync(url);
var res = JsonConvert.DeserializeObject<RootObject>(result);
sumName = res.psychoal3x.name;
}
}
public class Psychoal3x
{
public int id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int summonerLevel { get; set; }
public long revisionDate { get; set; }
}
public class RootObject
{
public Psychoal3x psychoal3x { get; set; }
}
The problem is that if I change my username to something else then it won't work since it will search for psychoal3x in the RootObject class. Anyone know how to fix this?
EDIT
Ok so i changed the code a bit and this is how it looks like
This is the modified code
try
{
using (var httpClient = new HttpClient())
{
HttpResponseMessage response = httpClient.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
string result = response.Content.ReadAsStringAsync().Result;
var data = JsonConvert.DeserializeObject<Dictionary<string, SummonerDto>>(result);
var name1 = data.First().Value.name;
var id = data.First().Value.id;
var profileIconId1 = data.First().Value.profileIconId;
var revisionDate1 = data.First().Value.revisionDate;
sumId = id;
sumProfileIconId = profileIconId1;
sumRevisionDate = revisionDate1;
System.Diagnostics.Debug.WriteLine("{0} this is the {1}", data.First().Value.name, data.First().Value.profileIconId);
}
}catch(Exception ex)
{ System.Diagnostics.Debug.WriteLine(ex.Message); }
public class SummonerDto
{
public int id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int summonerLevel { get; set; }
public long revisionDate { get; set; }
}
where sumName is the account name that is changed when the api is called.

You're close, but don't hardcode the username into your model classes. Assuming the API you are calling is this one, I'd recommend a structure like this:
public class SummonerDto
{
public int Id { get; set; }
public string Name { get; set; }
public int ProfileIconId { get; set; }
public int SummonerLevel { get; set; }
public long RevisionDate { get; set; }
}
According to the API docs, the return type is Dictionary<string, SummonerDto>. You can use JSON.NET to deserialize this easily:
var data = JsonConvert.DeserializeObject<Dictionary<string, SummonerDto>>(result);
That means that there will be a key-value pair with the key "psychoal3x" and a SummonerDto object as the value. You can get the first returned value by using First():
var summoner = data.First().Value;
From there, you can access all the properties, such as Name.
Here's a working fiddle based on the JSON data you posted in the comments: https://dotnetfiddle.net/xEUXa6

Related

Problem Deserialising JSON response from Wikipedia API

I am trying to use the Wikipedia search request API thus:
https://en.wikipedia.org/w/api.php?action=query&origin=*&format=json&generator=search&gsrnamespace=0&gsrlimit=100&gsrsearch=Simple Harmonic Motion
and then trying to deserialise thus:
WikiSearchResults R = s1.Deserialize<WikiSearchResults>(Json);
using this class structure:
private class WikiSearchQuery{
public WikiSearchPage[] pages { get; set; }
}
private class WikiSearchPage{
public int pageid { get; set; }
public string title { get; set; }
}
private class WikiSearchResults{
public WikiSearchQuery[] query { get; set; }
}
But I am getting this exception:
No parameterless constructor defined for type of WikiSearchQuery[]
I guess I am misinterpreting the JSON response. Can someone suggest what I am doing wrong?
There are probably multiple issues with deserializing.
As mentioned in the comments by fredrik, your classes are private. Making them public should fix the exception you get.
Additionally, the WikiSearchQuery only exists once and does not contain an array of objects, it does contain a dictionary.
This are the issues I see right now, so this might work:
public class WikiSearchQuery{
public Dictionary<string,WikiSearchPage> pages { get; set; }
}
public class WikiSearchPage{
public int pageid { get; set; }
public string title { get; set; }
}
public class WikiSearchResults{
public WikiSearchQuery query { get; set; }
}
using (var client = new HttpClient())
{
var _reqMessage = new HttpRequestMessage();
_reqMessage.Method = HttpMethod.Get;
_reqMessage.RequestUri = new Uri("https://en.wikipedia.org/w/api.php?action=query&origin=*&format=json&generator=search&gsrnamespace=0&gsrlimit=100&gsrsearch=S");
var response = client.SendAsync(_reqMessage);
response.Wait();
var result = response.Result;
var resultJson = result.Content.ReadAsStringAsync().Result;
var tes = JsonConvert.DeserializeObject<WikiSearchResults>(resultJson);
}
Models:
public class WikiSearchQuery
{
[JsonProperty("pages")]
public Dictionary<object, WikiSearchPage> Pages { get; set; }
}
public class WikiSearchPage
{
[JsonProperty("pageid")]
public int Pageid { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
}
public class WikiSearchResults
{
[JsonProperty("query")]
public WikiSearchQuery Query { get; set; }
}

Problems deserializing Json from MusixMatch API?

I'm trying to implement MusixMatch API, I must admit, when I debug I'm unable to see what's in the ObservableCollection after the API call because the debugger jumps to another thread (I have zero expertise in thread management), however I can see what's the from the API response, Visual Studio says is not Json formatted:
HttpClient httpClient = new HttpClient();
var response = await httpClient.GetStringAsync($"https://api.musixmatch.com/ws/1.1/artist.search?format=jsonp&callback=callback&q_artist=queen&page=1&page_size=5&apikey={apikey}");
RootObject testList= JsonConvert.DeserializeObject<RootObject>(response);
return testList;
I have a model with this structure:
public class Header
{
public int status_code { get; set; }
public double execute_time { get; set; }
public int available { get; set; }
}
public class ArtistNameTranslation
{
public string language { get; set; }
public string translation { get; set; }
}
public class ArtistNameTranslationList
{
public ArtistNameTranslation artist_name_translation { get; set; }
}
public class ArtistAliasList
{
public string artist_alias { get; set; }
}
public class ArtistCredits
{
public List<object> artist_list { get; set; }
}
public class Artist
{
public int artist_id { get; set; }
public string artist_name { get; set; }
public List<ArtistNameTranslationList> artist_name_translation_list { get; set; }
public string artist_comment { get; set; }
public string artist_country { get; set; }
public List<ArtistAliasList> artist_alias_list { get; set; }
public int artist_rating { get; set; }
public string artist_twitter_url { get; set; }
public ArtistCredits artist_credits { get; set; }
public int restricted { get; set; }
public DateTime updated_time { get; set; }
}
public class ArtistList
{
public Artist artist { get; set; }
}
public class Body
{
public List<ArtistList> artist_list { get; set; }
}
public class Message
{
public Header header { get; set; }
public Body body { get; set; }
}
public class RootObject
{
public Message message { get; set; }
}
}
As I said I was able to see what's in the response from the API, you can look at the complete response:
callback({"message":{"header": {"status_code":200,"execute_time":0.043232917785645,"available":6936},"body":{"artist_list":[{"artist":{"artist_id":118,"artist_name":"Queen","artist_name_translation_list":[{"artist_name_translation":{"language":"JA","translation":"\u30af\u30a4\u30fc\u30f3"}}],"artist_comment":"","artist_country":"","artist_alias_list":[{"artist_alias":"\u30af\u30a4\u30fc\u30f3"},{"artist_alias":"Queen + Adam Lambert"}],"artist_rating":99,"artist_twitter_url":"","artist_credits":{"artist_list":[]},"restricted":0,"updated_time":"2015-12-16T15:50:53Z"}},{"artist":{"artist_id":13755603,"artist_name":"Queen with David Bowie","artist_name_translation_list":[{"artist_name_translation":{"language":"EN","translation":"Queen"}}],"artist_comment":"","artist_country":"","artist_alias_list":[{"artist_alias":"Queen"}],"artist_rating":38,"artist_twitter_url":"","artist_credits":{"artist_list":[{"artist":{"artist_id":118,"artist_name":"Queen","artist_name_translation_list":[{"artist_name_translation":{"language":"JA","translation":"\u30af\u30a4\u30fc\u30f3"}}],"artist_comment":"","artist_country":"","artist_alias_list":[{"artist_alias":"\u30af\u30a4\u30fc\u30f3"},{"artist_alias":"Queen + Adam Lambert"}],"artist_rating":99,"artist_twitter_url":"","artist_credits":{"artist_list":[]},"restricted":0,"updated_time":"2015-12-16T15:50:53Z"}},{"artist":{"artist_id":431,"artist_name":"David Bowie","artist_name_translation_list":[{"artist_name_translation":{"language":"JA","translation":"\u30c7\u30f4\u30a3\u30c3\u30c9\u30fb\u30dc\u30a6\u30a4"}}],"artist_comment":"","artist_country":"GB","artist_alias_list":[{"artist_alias":"\u30c7\u30f4\u30a3\u30c3\u30c9\u30fb\u30dc\u30a6\u30a4"},{"artist_alias":"David Robert Jones"},{"artist_alias":"David Jones"},{"artist_alias":"Ziggy Stardust"},{"artist_alias":"\ub370\uc774\ube44\ub4dc \ubcf4\uc704"},{"artist_alias":"\u0414\u044d\u0432\u0438\u0434 \u0411\u043e\u0443\u0438"},{"artist_alias":"Davis Bowie"},{"artist_alias":"Bowie"},{"artist_alias":"\u30c7\u30d3\u30c3\u30c9\u30fb\u30dc\u30a6\u30a4"},{"artist_alias":"David Bowie"},{"artist_alias":"Davie Bowie"},{"artist_alias":"The Thin White Duke"}],"artist_rating":85,"artist_twitter_url":"","artist_credits":{"artist_list":[]},"restricted":0,"updated_time":"2018-10-20T16:37:59Z"}}]},"restricted":0,"updated_time":"2015-12-01T18:35:35Z"}},{"artist":{"artist_id":17057,"artist_name":"Queen Latifah","artist_name_translation_list":[{"artist_name_translation":{"language":"JA","translation":"\u30af\u30a4\u30fc\u30f3\u30fb\u30e9\u30c6\u30a3\u30d5\u30a1"}}],"artist_comment":"","artist_country":"US","artist_alias_list":[{"artist_alias":"\u30af\u30a4\u30fc\u30f3\u30fb\u30e9\u30c6\u30a3\u30d5\u30a1"},{"artist_alias":"Queen Latifa"},{"artist_alias":"Dana Owens"}],"artist_rating":46,"artist_twitter_url":"","artist_credits":{"artist_list":[]},"restricted":0,"updated_time":"2013-11-05T11:25:25Z"}},{"artist":{"artist_id":7321,"artist_name":"Queens of the Stone Age","artist_name_translation_list":[{"artist_name_translation":{"language":"RU","translation":"Queens Of The Stone Age"}}],"artist_comment":"","artist_country":"US","artist_alias_list":[{"artist_alias":"\u30af\u30a4\u30fc\u30f3\u30ba\u30aa\u30d6\u30b6\u30b9\u30c8\u30fc\u30f3\u30a8\u30a4\u30b8"},{"artist_alias":"Queens Of The Stone Age"},{"artist_alias":"shiqishidaihuanghou"},{"artist_alias":"Queen Of Stoneage"},{"artist_alias":"Queens Of The Stoneage"},{"artist_alias":"QOTSA"}],"artist_rating":76,"artist_twitter_url":"https:\/\/twitter.com\/qotsa","artist_credits":{"artist_list":[]},"restricted":0,"updated_time":"2015-12-09T18:04:11Z"}},{"artist":{"artist_id":26029011,"artist_name":"\u5973\u738b\u8702","artist_name_translation_list":[{"artist_name_translation":{"language":"EN","translation":"Queen Bee"}}],"artist_comment":"","artist_country":"JP","artist_alias_list":[{"artist_alias":"Queen Bee"}],"artist_rating":48,"artist_twitter_url":"","artist_credits":{"artist_list":[]},"restricted":0,"updated_time":"2019-07-15T13:55:16Z"}}]}}});
(https://drive.google.com/file/d/1RH9qxrCfKOXdX16eKy74iWhtbnfT46mD/view?usp=sharing)
As I said, Visual Studio is telling me that the response is not in Json>
(https://drive.google.com/file/d/1MoZlKEIbh8Epp_CC9gukWYtMBwp5oXwy/view?usp=sharing)
Looks like you are passing a parameter format=jsonp in the URL. JSONP is a format where JSON data is wrapped in a callback function. It is intended to be used from within <script> tags in HTML pages. If you want plain JSON, try changing that parameter to format=json and removing the corresponding callback parameter. Or you could try removing both format and callback parameters, assuming that JSON is the default format.
If that doesn't work, then the other alternative is to strip off the callback() function wrapper from the response string prior to trying to parse it as JSON. You can do that with a helper method like this:
public static string ExtractJson(string text)
{
int i = text.IndexOf('(');
int j = text.LastIndexOf(')');
return i > -1 && j > i ? text.Substring(i + 1, j - i - 1) : null;
}
You need to update your code to:
var response = await httpClient.GetStringAsync($"https://api.musixmatch.com/ws/1.1/artist.search?format=jsonp&callback=callback&q_artist=queen&page=1&page_size=5&apikey={apikey}");
var contents = await response.Content.ReadAsStringAsync();
RootObject testList= JsonConvert.DeserializeObject<RootObject>(contents);
return testList;

Restsharp Issues Deserialising

I'm trying to deserialise a JSON which conatains a series of "Clients" in succession from an API Call:
{"resource":[{"ClientID":1,"ClientName":"Name 1","ClientIntID":"TEST001","ClientCreatedDate":"2018-05-10 00:00:00"},{"ClientID":2,"ClientName":"Name 2","ClientIntID":"TEST002","ClientCreatedDate":"2018-05-10 03:10:47"},{"ClientID":3,"ClientName":"TestAPI","ClientIntID":"API001","ClientCreatedDate":"2018-05-10 03:30:14"},{"ClientID":4,"ClientName":"Postman","ClientIntID":"00POST","ClientCreatedDate":"2018-05-10 05:03:40"},{"ClientID":5,"ClientName":"Postman","ClientIntID":"00POST","ClientCreatedDate":"2018-05-10 05:04:28"},{"ClientID":6,"ClientName":"Postman","ClientIntID":"00POST","ClientCreatedDate":"2018-05-10 05:04:31"},{"ClientID":7,"ClientName":"Postman","ClientIntID":"00POST","ClientCreatedDate":"2018-05-10 05:10:32"},{"ClientID":8,"ClientName":"Postman","ClientIntID":"00POST","ClientCreatedDate":"2018-05-10 05:10:35"}]}
into a List of Clients.
This is my code to deserialise:
IRestResponse<List<Client>> response = restClient.Execute<List<Client>>(request);
var content = response.Content;
var data = response.Data;
//Trying to check output of each Client in List:
foreach(Client c in data)
{
Console.WriteLine(c.ClientName);
}
This is my Client Class:
public class Client
{
public int ClientID { get; set; }
public string ClientName { get; set; }
public string ClientIntID { get; set; }
public string ClientCreatedDate { get; set; }
}
I'm getting a list that is null, however when I change the code to simply cast into one Client only, it correctly stores the first client in the JSON response.
Any tips?
Your answer is in the form of the following format, so you have to deserialize into RootObject
public class Resource {
public int ClientID { get; set; }
public string ClientName { get; set; }
public string ClientIntID { get; set; }
public string ClientCreatedDate { get; set; }
}
public class RootObject{
public List<Resource> resource { get; set; }
}

Extract data from Json string

I got a string containing Json. It looks like this:
"status_code":200,
"status_txt":"OK",
"data":
{
"img_name":"D9Y3z.png",
"img_url":"http:\/\/s1.uploads.im\/D9Y3z.png",
"img_view":"http:\/\/uploads.im\/D9Y3z.png",
"img_width":"167",
"img_height":"288",
"img_attr":"width=\"167\" height=\"288\"",
"img_size":"36.1 KB",
"img_bytes":36981,
"thumb_url":"http:\/\/s1.uploads.im\/t\/D9Y3z.png",
"thumb_width":360,
"thumb_height":360,
"source":"http:\/\/www.google.com\/images\/srpr\/nav_logo66.png",
"resized":"0",
"delete_key":"df149b075ab68c38"
}
I am trying to get a hold of the "img_url". I have Json.NET installed and I´ve found similar questions here..
for example something like this:
JObject o = JObject.Parse("{'People':[{'Name':'Jeff'},{'Name':'Joe'}]}");
// get name token of first person and convert to a string
string name = (string)o.SelectToken("People[0].Name");
In my case I changed ("People[0].Name") to ("img_url"),("img_url[0]) etc..no luck
This is my code now:
public string tempJson { get; set; }
public ActionResult SaveUploadedFile(string test)
{
using (WebResponse wrs = wrq.GetResponse())
using (Stream stream = wrs.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
string json = reader.ReadToEnd();
tempJson = json;
}
}
Do I have to do something with the string before I can extract the value?
Thanks!
img_url is not a property of root object - it's a property of data object:
var obj = JObject.Parse(json);
var url = (string)obj["data"]["img_url"]; // http://s1.uploads.im/D9Y3z.png
Another option:
var url = (string)obj.SelectToken("data.img_url");
With help of this site
var obj = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(obj.data.img_url);
public class Data
{
public string img_name { get; set; }
public string img_url { get; set; }
public string img_view { get; set; }
public string img_width { get; set; }
public string img_height { get; set; }
public string img_attr { get; set; }
public string img_size { get; set; }
public int img_bytes { get; set; }
public string thumb_url { get; set; }
public int thumb_width { get; set; }
public int thumb_height { get; set; }
public string source { get; set; }
public string resized { get; set; }
public string delete_key { get; set; }
}
public class RootObject
{
public int status_code { get; set; }
public string status_txt { get; set; }
public Data data { get; set; }
}
You can also do the same thing with the use of dynamic keyword (without declaring above classes)
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine(obj.data.img_url);

ASP.NET Web API - How to deserialize a JSON

I am trying to consume an API.
I want to store following Request in an Object: http://api.swissunihockey.ch/rest/v1.0/clubs/655
The Problem is, that the Object is initialized but all the values are null.
I can receive the data and generate an output as a string. But the De-serialization to the Object doesn't work. Can you help?
private static async Task RunAsync()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://api.swissunihockey.ch/rest/v1.0/clubs/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage response = await client.GetAsync("615");
var club = await response.Content.ReadAsAsync<Club>();
Console.WriteLine(club.Name);
Console.Read();
}
catch (HttpRequestException e)
{
if (e.Source != null)
{
Console.WriteLine("HttpRequestException source: {0}", e.Source);
}
}
}
}
This is the Club class I am trying to store the data:
class Club
{
public int Id { get; set; }
public string Name { get; set; }
public string Street { get; set; }
public string Zip { get; set; }
public string City { get; set; }
public string Canton { get; set; }
public string Phone { get; set; }
public string Url { get; set; }
}
You need another class containing Club which will be deserialized further.
class Response
{
public Club Club { get; set; }
}
Then deserialize as
var res = await response.Content.ReadAsAsync<Response>();
var club = res.Club;
Once you have the string from the response, use the package that Web API already references from Nuget, Json.Net by Newtonsoft.Json1, and call Club c = JsonConvert.Deserialize<Club>(responseString);
I find this to be far simpler than the built in Data Contracts already mentioned.
Try to look on the microsoft related documentation:
http://msdn.microsoft.com/en-us/library/hh674188.aspx
You need to create a data contract and then process the request with this contract.
For example for your, the data contract may be something like:
[DataContract]
class Club
{
[DataMember(Name = "Id")]
public int Id { get; set; }
[DataMember(Name = "Name")]
public string Name { get; set; }
[DataMember(Name = "Street")]
public string Street { get; set; }
[DataMember(Name = "Zip")]
public string Zip { get; set; }
[DataMember(Name = "City")]
public string City { get; set; }
[DataMember(Name = "Canton")]
public string Canton { get; set; }
[DataMember(Name = "Phone")]
public string Phone { get; set; }
[DataMember(Name = "Url")]
public string Url { get; set; }
}
Then look at chapter "process the request" of the documentation to handle your data.

Categories