1

I'm using a HTTP client to get a string and picking out my json from that and converting back to a string to deserialize it into a List of "Spots" but can't get it to to work

I've tried changing the DeserializeObject type to every mix of "List, IList, HardwareUpdateSpot, HardWareModel" and still it didn't work

public async Task<IList<HardwareUpdateSpot>> UpdateSpotHTTP()
{
    var client = new HttpClient();
    var response = await client.GetAsync(
        "https://io.adafruit.com/api/v2/Corey673/feeds/673d855c-9f66-4e49-8b2c-737e829d880c");
    var responseHTTP =  response.Content.ReadAsStringAsync();

    var j = JObject.Parse(responseHTTP.Result);
    var b = j.GetValue("last_value");
    var h = b.ToString();


    var dataObjects = JsonConvert.DeserializeObject<IList<HardwareUpdateSpot>>(h);

    return null;
}

public record HardWareModel
{
    public int SpotId { get; set; }
    public string Occupied { get; set; }
}

public class HardwareUpdateSpot
{
    public IList<HardWareModel> Spots { get; set; }

    public HardwareUpdateSpot(IList<HardWareModel> spots)
    {
        Spots = spots;
    }
}
Steve
  • 213,761
  • 22
  • 232
  • 286
Corey673
  • 23
  • 4
  • I tried to but the formatting came out wrong ill edit it in – Corey673 Feb 03 '23 at 16:51
  • You are asking to deserialize a IList but you get back a single HardwareUpdateSpot that contains a list of HardWareModel – Steve Feb 03 '23 at 17:13
  • Also you need to provide a parameterless constructor for HardwareUpdateSpot and the property Spots should be named Spot as your json names it (or use the _[JsonProperty("Spot")]_ attribute) – Steve Feb 03 '23 at 17:15

1 Answers1

0

While trying to reproduce your problem I have examined the returned value from the API call. This is the json returned:

{"Spot":[
    {"SpotId":"1","Occupied":"false",}, 
    {"SpotId":"2","Occupied":"false",}, 
    {"SpotId":"3","Occupied":"false",}, 
    {"SpotId":"4","Occupied":"false"}
]}

So, it easy to see that the returned json requires a root object with a public Spot property (not Spots) and this property should be a collection.
Instead the code above expects a json that has at the root level a collection of HardwareUpdateSpot and of course it cannot work.
To fix the problem you need to change the deserialization to:

JsonConvert.DeserializeObject<HardwareUpdateSpot>(h);

Now, you need to make some changes to the HardwareUpdateSpot class to make it compatible with the json.

First you need to add a parameterless constructor required by jsonconvert, then you need to fix the difference between the name for the property (Spots) and the name returned (Spot).
So you can change the property name to match the json or add the attribute that make Spots=Spot

[JsonProperty("Spot")]
public IList<HardWareModel> Spots { get; set; }
Steve
  • 213,761
  • 22
  • 232
  • 286