30

I am testing my Web API. Mocking the data I have this:

var objs = ((JArray)JsonConvert.DeserializeObject("{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}")).Values<JObject>();

Which gives me the error:

Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Newtonsoft.Json.Linq.JArray'

The thing is it was working. I must have changed something, but I don't know what.

My intent is to convert this JSON object to a list of .NET objects called Print which has the fields:

PrintId
Header
TX
CompnayRef
Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
Andrew Simpson
  • 6,883
  • 11
  • 79
  • 179

4 Answers4

44

Just make a class and deserialize it.

public class Print
{
    public int PrintId { get; set; }
    public string Header { get; set; }
    public string TC { get; set; }
    public string CompanyRef { get; set; }
}

Print printObj = JsonConvert.DeserializeObject<Print>(yourJson);
printObj.PrintId = //...
Camo
  • 1,122
  • 10
  • 15
  • 1
    If say, Print had a sub object that was an arraylist, how would you deserialize that so that the arraylist wasn't still in json format? – CBC_NS Oct 01 '16 at 19:31
  • @CBC_NS Just like you would do it now, add the property to the print class (like `public List PropertyName { get; set; }`) and deserialize it as described. – Camo Oct 04 '16 at 10:33
  • @Rinecamo Are you saying deserialize each subobject as you would the parent object; I can't deserialize the parent and child objects all at once? – CBC_NS Oct 04 '16 at 16:05
  • @CBC_NS Deserialize the parent object and it will automatically deserialize the sub objects. – Camo Oct 06 '16 at 05:51
  • @Rinecamo I've tried doing that, and it only deserializes the parent. I have had to loop through the sub objects and deserialize them one by one, and then loop through each sub objects sub objects. =/ Is there a setting you have to pass in to achieve this? – CBC_NS Oct 06 '16 at 12:32
  • @CBC_NS Then I guess you are doing it the wrong way, wanna provide some code? – Camo Oct 07 '16 at 11:42
12

As the message says, your object is JObject so don't cast it to JArray. Try this:

var objs = JsonConvert.DeserializeObject("{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}");

Update To get a collection List<Print>, your JSON needs to be an array. Try this (I made your JSON an array and added a second object):

string json = "[{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}"
            + ",{ \"PrintId\":20,\"Header\":\"header2\",\"TC\":\"tc2\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}]";
var objs = JsonConvert.DeserializeObject<List<Print>>(json);

//The loop is only for testing. Replace it with your code.
foreach(Print p in objs){
    Console.WriteLine("PrintId: " + p.PrintId);
    Console.WriteLine("Header: " + p.Header);
    Console.WriteLine("TC: " + p.TC);
    Console.WriteLine("CompanyRef: " + p.CompanyRef);
    Console.WriteLine("==============================");
}

public class Print
{
    public int PrintId { get; set; }
    public string Header { get; set; }
    public string TC { get; set; }
    public string CompanyRef { get; set; }
}

Here is a fiddle.

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
  • 1
    It's *already a JObject*, that's what the error message is talking about – Panagiotis Kanavos Nov 03 '15 at 09:39
  • Yes, I forgot to delete it at the end of the line. Try it now. – Racil Hilan Nov 03 '15 at 09:44
  • Hi, it does not error this time but how do i get it into my List collection? – Andrew Simpson Nov 03 '15 at 09:45
  • @AndrewSimpson the answerer posted this before your edit. In the future, be sure to explain what your *actual* problem is, not the problem with your attempted solution. If you had, everyone would have answered that Json.NET can parse Json to strongly-typed objects. There's even a name for such kinds of questions, [the XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Panagiotis Kanavos Nov 03 '15 at 09:49
  • 2
    To get a collection `List`, your JSON needs to be an array. Check my update. – Racil Hilan Nov 03 '15 at 09:59
  • @PanagiotisKanavos Hi, you were right (re: other question). It was my rubbish code. Issue was with async Thread structures.. apologies – Andrew Simpson Nov 03 '15 at 13:24
3

Simply because { } is a jobject notation, to make it a jarray just put square brackets around it e.g. [{ }]. So in your case, just putting these two chars fixes the problem.

var objs = ((JArray)JsonConvert.DeserializeObject("[{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}]")).Values<JObject>();

you can try here https://dotnetfiddle.net/RmgGw8

Note: You said it was working before. So this string input probably is a result of a serialization. You did not have a problem before, because your input was always an array with multiple items until this one. And your serializer is probably producing a single object (output starting with '{') instead of an array (output starting with '[') for single item arrays.

serializing List with single object as JSON object not JSON array

ozanmut
  • 2,898
  • 26
  • 22
1

For me I was putting empty string as an object which caused the issue, I switched to "{}" which fixed my issue

Andrew
  • 11
  • 1