I learned how to get information from an API using the microsoft docs, the microsoft docs don't show how to get nested/layers deep objects. The only video I found that showed how to do it did it something like this. However I can't get it to work, receiving only an error stating this:
"Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Dashboard.Weather' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly."
Any help is appreciated, i'm trying to get the "Weather.description", here's my sample code:
public class Weather
{
public string Description{ get; set; }
}
public class Product
{
public Weather Weather { get; set; }
}
public static class ApiHelper
{
static string city_id = "CITY_ID";
static string api_key = "API_KEY";
public static HttpClient client = new HttpClient();
public static void InitializeClient()
{
client.BaseAddress = new Uri($"http://api.openweathermap.org/data/2.5/weather?id={city_id}&APPID={api_key}");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public static async Task<Weather> GetProductAsync()
{
Product product = null;
HttpResponseMessage response = await client.GetAsync("");
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product.Weather;
}
}
async void SetLabelText()
{
var weather = await ApiHelper.GetProductAsync();
descriptionLabel.Text = $"Description: {weather.Description}";
}
The response from the API is formatted as follows
{"coord":{"lon":-89.59,"lat":41.56},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":279.27,"feels_like":275.4,"temp_min":278.15,"temp_max":280.37,"pressure":1027,"humidity":74},"visibility":16093,"wind":{"speed":3.1,"deg":200},"clouds":{"all":1},"dt":1576951484,"sys":{"type":1,"id":3561,"country":"US","sunrise":1576934493,"sunset":1576967469},"timezone":-21600,"id":4915397,"name":"Walnut","cod":200}
Your Product model does not correctly align with the json you are receiving.
The json you've post has weather as a list, but Product assumes it will just be an object. The json parser, then, correctly fails when seeing it is an array in the actual json instead of a JSON object.
The fix should be simple; Product.Weather should be of type List<Weather> (or IEnumerable<Weather> or Weather[], whichever fits your needs).
I am trying to make a simple program that can automate price checking using data from json, however I haven't used json before and I'm not quite sure what I need to do get get the desired result.
Effectively I'm trying to convert this PHP into c#. (http://www.sourcecodester.com/tutorials/php/8042/api-json-parsing-php.html)
<?php
$src = file_get_contents('https://www.g2a.com/marketplace/product/auctions/?id=256');
$json = json_decode($src, true);
foreach ($json as $k=>$v) {
if (is_array($v)) {
foreach($v as $key=>$value) {
if (is_array($value)) {
foreach($value as $arKey => $arValue) {
if ($arKey == 'p') {
echo $arValue . '<br/>';
}
}
}
}
}
}
?>
I've tried a few things such as JsonConvert.DeserializeObject(webJson) and JObject.Parse(webJson), but I'm just not sure where I should be looking or how to go about doing it.
I have the first part:
internal static string GetWebContent(string #ID)
{
var wc = new WebClient();
string response = wc.DownloadString(#"https://www.g2a.com/marketplace/product/auctions/?id=" + #ID);
return response;
}
A response looks like this: (https://www.g2a.com/marketplace/product/auctions/?id=27446)
{"a":{"k_709942":{"c":"pl","tr":3451,"f":"\u00a324.71","fb":"\u00a327.18","ci":"565784","cname":"Marketplace User","p":"24.7098173","pb":"27.18431394","ep":"35.15","epb":"38.67","a":"709942","it":"game","t":"1","sl":"0","l":null,"lt":null,"x":0,"v":"all","so":0,"r":99},"k_763218":{"c":"pl","tr":1120,"f":"\u00a324.74","fb":"\u00a327.22","ci":"6533797","cname":"User #f36726dcd","p":"24.7449664","pb":"27.21946304","ep":"35.20","epb":"38.72","a":"763218","it":"game","t":"0","sl":"0","l":null,"lt":"0","x":0,"v":"all","so":0,"r":92},"k_799750":{"c":"pl","tr":559,"f":"\u00a324.78","fb":"\u00a327.26","ci":"6115711","cname":"Marketplace User","p":"24.7801155","pb":"27.26164196","ep":"35.25","epb":"38.78","a":"799750","it":"game","t":null,"sl":"0","l":null,"lt":null,"x":0,"v":"retail","so":0,"r":98},"k_722082":{"c":"gb","tr":49066,"f":"\u00a324.96","fb":"\u00a327.45","ci":"1047917","cname":"Marketplace User","p":"24.955861","pb":"27.4514471","ep":"35.50","epb":"39.05","a":"722082","it":"game","t":"1","sl":"0","l":null,"lt":"0","x":0,"v":"all","so":0,"r":98},"k_718113":{"c":"pl","tr":5852,"f":"\u00a324.96","fb":"\u00a327.45","ci":"226876","cname":"Marketplace User","p":"24.955861","pb":"27.4514471","ep":"35.50","epb":"39.05","a":"718113","it":"game","t":"1","sl":"0","l":null,"lt":"0","x":0,"v":"all","so":0,"r":98},"k_739155":{"c":"pl","tr":1208,"f":"\u00a325.43","fb":"\u00a327.98","ci":"6540559","cname":"User #1f948a6a66249","p":"25.43316468854","pb":"27.976481157394","ep":"35.30","epb":"38.83","a":"739155","it":"game","t":"0","sl":"0","l":null,"lt":"0","x":0,"v":"all","so":0,"r":89},"k_795049":{"c":"pl","tr":50420,"f":"\u00a325.86","fb":"\u00a328.45","ci":"2498689","cname":"Marketplace User","p":"25.86270778","pb":"28.44968154","ep":"36.79","epb":"40.47","a":"795049","it":"game","t":"1","sl":"0","l":null,"lt":"0","x":0,"v":"all","so":0,"r":99},"k_816132":{"c":"pl","tr":22,"f":"\u00a326.00","fb":"\u00a328.60","ci":"6208533","cname":"Marketplace User","p":"25.99627436","pb":"28.59730776","ep":"36.98","epb":"40.68","a":"816132","it":"game","t":"0","sl":"0","l":null,"lt":"0","x":0,"v":"retail","so":0,"r":0},"k_809925":{"c":"pl","tr":81021,"f":"\u00a326.00","fb":"\u00a328.60","ci":"407513","cname":"Marketplace User","p":"26.00330418","pb":"28.60433758","ep":"36.99","epb":"40.69","a":"809925","it":"game","t":"1","sl":"0","l":null,"lt":"0","x":0,"v":"retail","so":0,"r":100},"k_815898":{"c":"cl","tr":1,"f":"\u00a326.01","fb":"\u00a328.61","ci":"7524623","cname":"Marketplace User","p":"26.010334","pb":"28.6113674","ep":"37.00","epb":"40.70","a":"815898","it":"game","t":null,"sl":"0","l":null,"lt":null,"x":0,"v":"retail","so":0,"r":0},"k_711901":{"c":"pl","tr":12194,"f":"\u00a326.51","fb":"\u00a329.16","ci":"286793","cname":"Marketplace User","p":"26.506689203722","pb":"29.158078610346","ep":"36.79","epb":"40.47","a":"711901","it":"game","t":"1","sl":"0","l":null,"lt":null,"x":0,"v":"all","so":0,"r":99},"k_748710":{"c":"pt","tr":66460,"f":"\u00a326.65","fb":"\u00a329.32","ci":"440288","cname":"Marketplace User","p":"26.650786454082","pb":"29.316585585742","ep":"36.99","epb":"40.69","a":"748710","it":"game","t":"1","sl":"0","l":null,"lt":"0","x":0,"v":"all","so":0,"r":100},"k_709464":{"c":"pl","tr":121341,"f":"\u00a327.02","fb":"\u00a329.72","ci":"1072530","cname":"User #3285e5f8dfcb2","p":"27.0182344425","pb":"29.72005788675","ep":"37.50","epb":"41.25","a":"709464","it":"game","t":"1","sl":"0","l":null,"lt":"0","x":0,"v":"retail","so":0,"r":100},"k_709805":{"c":"pl","tr":11708,"f":"\u00a328.09","fb":"\u00a330.90","ci":"1043113","cname":"User #ca1965d0354a","p":"28.091758957682","pb":"30.901655339702","ep":"38.99","epb":"42.89","a":"709805","it":"game","t":"1","sl":"0","l":null,"lt":null,"x":0,"v":"retail","so":0,"r":100},"k_725839":{"c":"es","tr":1,"f":"\u00a331.99","fb":"\u00a335.18","ci":"7023396","cname":"Marketplace User","p":"31.985681","pb":"35.1842491","ep":"45.50","epb":"50.05","a":"725839","it":"game","t":null,"sl":"0","l":null,"lt":null,"x":0,"v":"retail","so":0,"r":0},"k_0":{"f":"\u00a332.33","fb":"\u00a335.56","p":"32.33014218","pb":"35.563156398","ep":"45.99","epb":"50.59","a":0,"c":"","rc":"","r":"","tr":0,"t":1,"so":0,"x":0,"n":"G2A.com"}},"w":0}
Any help with will greatly appreciated.
Thanks in advace
So Json is a way for two languages to pass objects to each other. It's just a way to encode an object, so the first part would be to create an object that matches the Json encoding. I was unable to see your example, so I will give you one of my own.
{"Aggregates": [{"ColumnName": "Some Value", "AggregateFunction": "Some Other Value"}], "GroupBy": true}
I would then create a class like this one.
public class JsonAggregates
{
public List<Aggregate> Aggregates { get; set; }
public string GroupBy { get; set; }
}
public class Aggregate
{
public string ColumnName {get; set;}
public string AggregateFunction {get; set;}
}
You can then encode the Json to this new data type with the following code.
using (Stream s = GenerateStreamFromString(json))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JsonAggregates));
JsonAggregates aggregate = (JsonAggregates)serializer.ReadObject(s);
}