Search code examples
c#jsonsilverlightcollectionsjson-deserialization

Newsoft Json deserialize into products Collection not working


I am creating a windows phone silver light 8 app.

I have a Json string and I am trying to convert it into a List of objects and each object is a object of a class classed "Product" and list is supposed to be products. ultimately I want it to convert into Observable collection so that I can bind that collection to my listbox in my windows Silverlight phone app.

Here is my class

public class Product
{
    public string _id { get; set; }
    public string code { get; set; }
    public string name { get; set; }
    public string imgAddress { get; set; }
    public int queryCount { get; set; }
}

Here is code to deserialize the json

var PDS = "{\"products\":[{\"_id\":\"58b2\",\"code\":\"59034\",\"name\":\"somename1\",\"imgAddress\":\"https://someimageurl/.../.jpg\",\"queryCount\":0},{\"_id\":\"58b3\",\"code\":\"59035\",\"name\":\"somename2\",\"imgAddress\":\"https://someimageurl2/.../.jpg\",\"queryCount\":1}]}";
var pds = JsonConvert.DeserializeObject<List<Product>>(PDS);
//PDS is actually very long string and the array products has a lot of objects but I am only writing 2 products here for simplicity.

Here is my collection for binding

public ObservableCollection<Product> Products { get; set; }

ERRORS >> First I was getting parsing error so I escaped all quotes within the string like this \" **>>**But then it was only converting to a normal string like object but I want to convert to a collection of products of type "Product"

>> Exception

Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[PivotApp1.Product]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

Path 'products', line 1, position 12.

Thanks in advance


Solution

  • You can deserialize it this way (but you'll have somehow to reformat your JSON string):

    from

    var PDS = "{"products":[{"_id":"58b2","code":"59034","name":"somename1","imgAddress":"https://someimageurl/.../.jpg","queryCount":0},{"_id":"58b3","code":"59035","name":"somename2","imgAddress":"https://someimageurl2/.../.jpg","queryCount":1}]}";
    //PDS is actually very long string and the array products has a lot of objects but I am only writing 2 products here for simplicity.
    

    to

    var PDS = "[{'_id':'58b2','code':'59034','name':'somename1','imgAddress':'https://someimageurl/.../.jpg','queryCount':0},{'_id':'58b3','code':'59035','name':'somename2','imgAddress':'https://someimageurl2/.../.jpg','queryCount':1}]";
    //PDS is actually very long string and the array products has a lot of objects but I am only writing 2 products here for simplicity.
    

    Then

    var pds = JsonConvert.DeserializeObject<List<Product>>(PDS);
    

    More infos --> Deserialize a collection

    No need of creating another class as suggested!

    EDIT: Actually you get this exception because your JSON string represents an object 'products' containing a list of 'Product' and this doesn't directly relate to your root class.

    This is what your current JSON look like:

    Your current JSON string

    Your JSON string result should be something like that instead:

    var PDS = "[{'_id':'58b2','code':'59034','name':'somename1','imgAddress':'https://someimageurl/.../.jpg','queryCount':0},{'_id':'58b3','code':'59035','name':'somename2','imgAddress':'https://someimageurl2/.../.jpg','queryCount':1}]";
    

    Represented as following (notice the slight difference):

    Correct JSON string for List<Product> type

    Using this JSON string, it will work with no exception raised:

    var pds = JsonConvert.DeserializeObject<List<Product>>(PDS);
    

    Or, if you can't change the resulting JSON string in PDS, you can do what J. Tuc suggested (via a new "RootClass").