3

Can anyone tell me why I get an error when trying to output"dJson2.Type" in the code below?

    string Json1= @"[{'Id':1, 'FirstName':'John', 'LastName':'Smith'}, {'Id':2, 'FirstName':'Jane', 'LastName':'Doe'}]";
    dynamic dJson1= JsonConvert.DeserializeObject(Json1);
    Console.WriteLine(dJson1.GetType());
    Console.WriteLine(dJson1.Type);

    string Json2 = @"{'Id':1, 'FirstName':'John', 'LastName':'Smith'}";
    dynamic dJson2 = JsonConvert.DeserializeObject(Json2);
    Console.WriteLine(dJson2.GetType());
    Console.WriteLine(dJson2.Type);

The program dies on the Console.WriteLine(dJson2.Type) statement. The output of the program is...

Newtonsoft.Json.Linq.JArray
Array
Newtonsoft.Json.Linq.JObject
(should say Object here, I think)

Inspecting the local variables, dJson2 has a "Type" property with value "Object".

7
  • 1
    What error do you get? Commented Sep 30, 2016 at 22:27
  • Yeah, the error message should tell you exactly what's wrong. Commented Sep 30, 2016 at 22:29
  • The call is ambiguous between the following methods or properties: 'System.Console.WriteLine(string, params object[])' Commented Sep 30, 2016 at 22:30
  • 2
    I'm taking a shot in the dark here - I think in the first example the compiler is smart enough to figure out it's an array. But in the second example it's looking for a property called Type, and it doesn't exist. Borrowing your code, as soon as I explicitly put in a property called Type in your JSON string, it compiled as expected. Commented Sep 30, 2016 at 22:37
  • In answer to Stanley/Harvey. The error actually doesn't help much. The problem is that the Type property if dJson2 is coming back with a null value. You can, for instance, add "var jType = dJson2.Type" in the code and you will find that jType is null. Commented Oct 1, 2016 at 1:10

1 Answer 1

1

This is because JObject behaves similarly as System.Dynamic.ExpandoObject. Try to change your example to:

  string Json2 = @"{'Id':1, 'FirstName':'John', 'LastName':'Smith'}";
  dynamic dJson2 = JsonConvert.DeserializeObject(Json2);
  dJson2.Type = "mynewfield";
  Console.WriteLine(dJson2.GetType());
  Console.WriteLine(dJson2.Type);

If you want to get property of underlying type you need to cast it (to JToken or JObject), otherwise requested property will be searched in IDictionary<string, JToken> that JObject implements.

This example may help:

  dynamic oobj = new JObject();
  oobj.Type = "TEST";
  Console.WriteLine(oobj.Type);
  Console.WriteLine(((JObject)oobj).Type);
Sign up to request clarification or add additional context in comments.

1 Comment

Huh. Makes sense, though I'm not sure the behavior is what I like or what I would expect. It's weird that it works for JArray but not JObject. Anyway, a cast definitely works. What I ended out doing was a switch on dJson2.GetType(), casting to the actual type, then moving on. This behaves as expected, if somewhat verbose.... Thanks for explaining, DolphinSX.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.