20

I have a JSON object, something like:

var jsonObject = {"att1" : "val1","att2" : "val2","att3" : "val3","att4" : "val4"}

I need to convert the same into an ExpandoObject.

I tried something like:

var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<List<ExpandoObject>>(jsonObject, 
                                                                 expConverter);

But it is not giving me the desired result.

Can someone help me get the result?

Matt
  • 25,467
  • 18
  • 120
  • 187
satish kumar V
  • 1,695
  • 6
  • 33
  • 47
  • 5
    "But It is not giving the result" doesn't tell us what *does* happen. Please show a short but complete program which demonstrates the problem, including expected and actual results. – Jon Skeet Mar 16 '15 at 10:30
  • 1
    You should not use `dynamic`. Just typecast the whole thing to `List` – Erwin Mar 16 '15 at 10:31
  • 3
    You are trying to convert a non array JSON into a List<>. If you looked at the error that your code produces when run, you would see that the error is telling you that you are trying to do that – Bernd Linde Mar 16 '15 at 10:31
  • 1
    Additionally, the JSON indeed isn't an array, so it won't convert to one in c# :) – Erwin Mar 16 '15 at 10:32
  • 1
    `dynamic obj = JsonConvert.DeserializeObject(jsonObject, expConverter);` works just fine... – stefankmitph Mar 16 '15 at 10:42

2 Answers2

28
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(jsonObject, expConverter);

Your JSON object isn't an array, so you can't serialize to a List<>. Just serialize to the object directly instead.

zcoop98
  • 2,590
  • 1
  • 18
  • 31
Ch K V S Kumar
  • 475
  • 4
  • 13
  • 1
    **Hint:** If you're exploring that in **LinqPad,** you need to convert it to an object before you dump it, like: `((object)obj).Dump();` That will show the entire object. – Matt Feb 22 '22 at 08:16
  • That doesn't seem to work for deeply nested structures. – Casper Bang Jun 10 '22 at 08:42
1

I see two issues, preventing the code to work:

  1. The syntax of your jsonObject declaration is not correct. Declare it as a string and inside the string use the escape "backslash + double quote" for every double quote:
    var jsonObject = "{\"att1\": \"val1\",\"att2\": \"val2\",\"att3\": \"val3\",\"att4\": \"val4\"}";

  2. Then, when using Newtonsoft.Json.Converters, instead of List<ExpandoObject> it needs to be ExpandoObject in the type argument, because an ExpandoObject is inside already a dictionary (not a list):
    dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(jsonObject, expConverter);

The following code fixes the two issues mentioned above and displays the key/value pairs on screen:

using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

void Main()
{
  // 1. this needs to be a string
  var jsonObject =  
    "{\"att1\": \"val1\",\"att2\": \"val2\",\"att3\": \"val3\",\"att4\": \"val4\"}";

  var expConverter = new ExpandoObjectConverter();

  // 2. the correct type argument is ExpandoObject
  dynamic obj = 
              JsonConvert.DeserializeObject<ExpandoObject>(jsonObject, expConverter);

  // display the keys and values on screen
  foreach (var o in obj)
  {
    Console.WriteLine($"{o.Key}, {o.Value}");
  }
}

The output is:

att1, val1
att2, val2
att3, val3
att4, val4

Note: You can easily convert the expando to a dictionary (internally it already is an IDictionary) like:

var dict = new Dictionary<string, object>(obj);

That allows to do a dict.Dump() in LinqPad (not supported with ExpandoObject)


If you're trying it out in LinqPad press F4 and add the NUGET package Json.NET (if you don't have the paid version of LinqPad, NUGET function is limited there - try Rock.Core.Newtonsoft in this case).

Matt
  • 25,467
  • 18
  • 120
  • 187