简体   繁体   中英

Value from deserialized JSON string is 0

I'm trying to get the amount of pieces belonging to a certain Lego set using the Brickset API ( https://brickset.com/article/52664/api-version-3-documentation ) When writing the Json string to the console it displays the amount of pieces correct. Howeever after deserializing and then writing only the value of pieces to the console it displays 0. All other properties are also not displayed when written to the console.

Result after writing the Json string to the console

{"status":"success","matches":1,"sets":\[
{
"setID": 31844,
"number": "10293",
"numberVariant": 1,
"name": "Santa's Visit",
"year": 2021,
"theme": "Icons",
"themeGroup": "Model making",
"subtheme": "Winter Village Collection",
"category": "Normal",
"released": true,
"pieces": 1445,
"minifigs": 4,
"image": {
"thumbnailURL": "https://images.brickset.com/sets/small/10293-1.jpg",
"imageURL": "https://images.brickset.com/sets/images/10293-1.jpg"
},
"bricksetURL": "https://brickset.com/sets/10293-1",
"collection": {},
"collections": {
"ownedBy": 9350,
"wantedBy": 2307
},
"LEGOCom": {
"US": {
"retailPrice": 99.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
},
"UK": {
"retailPrice": 89.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
},
"CA": {
"retailPrice": 139.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
},
"DE": {
"retailPrice": 99.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
}
},
"rating": 4.3,
"reviewCount": 0,
"packagingType": "Box",
"availability": "LEGO exclusive",
"instructionsCount": 15,
"additionalImageCount": 13,
"ageRange": {
"min": 18
},
"dimensions": {
"height": 28.0,
"width": 47.9,
"depth": 8.7,
"weight": 1.656
},
"barcode": {
"EAN": "5702016914313"
},
"extendedData": {
"tags": \[
"Santa Claus|n",
"18 Plus",
"Baked Goods",
"Bedroom",
"Bird",
"Brick Built Tree",
"Brick Separator",
"Christmas",
"Christmas Tree",
"D2c",
"Fireplace",
"Furniture",
"House",
"Kitchen",
"Light Brick",
"Mail",
"Microscale",
"Musical",
"Rocket",
"Seasonal",
"Winter Village"
\]
},
"lastUpdated": "2022-10-03T08:24:39.49Z"
}
\]}

Main Code

class Program
{

        static async Task Main(string[] args)
        {
            await askSetNumber();
        }
    
        private async Task GetPosts(string url)
        {
    
            HttpClient client = new HttpClient();
    
            string response = await client.GetStringAsync(url);
            Console.WriteLine(response);
    
            var set = JsonConvert.DeserializeObject<Rootobject>(response);
            Console.WriteLine(set.pieces); 
        }
    
        static async Task askSetNumber()
        {
            Console.WriteLine("Please enter a setnumber: ");
            string setNumber = "{'setNumber':'" + Console.ReadLine().ToString() + "-1'}";
            string url = "https://brickset.com/api/v3.asmx/getSets?apiKey=[APIKey here]&userHash=&params=" + setNumber;
            Console.WriteLine(url);
            Program program = new Program();
            await program.GetPosts(url);
        }
    }

I made all classes by Pasting the Json as classes, This is the class of the object I need the data off

public class Rootobject
    {
        public int setID { get; set; }
        public string number { get; set; }
        public int numberVariant { get; set; }
        public string name { get; set; }
        public int year { get; set; }
        public string theme { get; set; }
        public string themeGroup { get; set; }
        public string subtheme { get; set; }
        public string category { get; set; }
        public bool released { get; set; }
        public int pieces { get; set; }
        public int minifigs { get; set; }
        public Image image { get; set; }
        public string bricksetURL { get; set; }
        public Collection collection { get; set; }
        public Collections collections { get; set; }
        public Legocom LEGOCom { get; set; }
        public float rating { get; set; }
        public int reviewCount { get; set; }
        public string packagingType { get; set; }
        public string availability { get; set; }
        public int instructionsCount { get; set; }
        public int additionalImageCount { get; set; }
        public Agerange ageRange { get; set; }
        public Dimensions dimensions { get; set; }
        public Barcode barcode { get; set; }
        public Extendeddata extendedData { get; set; }
        public DateTime lastUpdated { get; set; }
    }

I tried the example from How to get some values from a JSON string in C#? but set.pieces keeps returning 0.

This is my first time trying this kind of stuff, but I am stuck on this part.

Rootobject does not contain the same information as the json string you outputted to the console (it also escapes square brackets for some reason), so you either need to specify the entire object or navigate the json tree to get the value you require.

This is not a particularly good or robust solution, but you could replace the var set portion of you code with:

        JsonDocument doc = JsonDocument.Parse(response);
        if (!doc.RootElement.TryGetProperty("sets", out JsonElement sets)) return;
        foreach(var set in sets.EnumerateArray())
        {
            if (!set.TryGetProperty("pieces", out JsonElement pieces)) continue;
            Console.WriteLine(pieces.GetInt32());
        }

(You'll also need using System.Text.Json; rather than the newtonsoft one.)

you have you json at first,since you have some strange "/" chars, after this you have to fix your classes too

json=json.Replace("\\[","[").Replace("\\]","]");

 Set set = JsonConvert.DeserializeObject<Set>(json);

public class Set
{
    public string status { get; set; }
    public int matches { get; set; }
    public List<SetItem> sets { get; set; }
}

public class SetItem
{
    public int setID { get; set; }
    public string number { get; set; }
    public int numberVariant { get; set; }
    public string name { get; set; }
    public int year { get; set; }
    public string theme { get; set; }
    public string themeGroup { get; set; }
    public string subtheme { get; set; }
    public string category { get; set; }
    public bool released { get; set; }
    public int pieces { get; set; }
    public int minifigs { get; set; }
    public Image image { get; set; }
    public string bricksetURL { get; set; }
    public Collection collection { get; set; }
    public Collections collections { get; set; }
    public LEGOCom LEGOCom { get; set; }
    public double rating { get; set; }
    public int reviewCount { get; set; }
    public string packagingType { get; set; }
    public string availability { get; set; }
    public int instructionsCount { get; set; }
    public int additionalImageCount { get; set; }
    public AgeRange ageRange { get; set; }
    public Dimensions dimensions { get; set; }
    public Barcode barcode { get; set; }
    public ExtendedData extendedData { get; set; }
    public DateTime lastUpdated { get; set; }
}
public class LEGOCom
{
    public Country US { get; set; }
    public Country UK { get; set; }
    public Country CA { get; set; }
    public Country DE { get; set; }
}
public class AgeRange
{
    public int min { get; set; }
}

public class Barcode
{
    public string EAN { get; set; }
}

public class Country
{
    public double retailPrice { get; set; }
    public DateTime dateFirstAvailable { get; set; }
}

and maybe it make some sense to define LEGOCom as a Dictionary, if you have much more countries

public Dictionary<string,Country> LEGOCom { get; set; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM