Home > Blockchain >  Why can't I deserialize string Into a model?
Why can't I deserialize string Into a model?

Time:02-04

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;
    }
}

CodePudding user response:

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; }
  • Related