32

I'm parsing a JSON string using the NewtonSoft JObject. How can I get values from a dynamic object programmatically? I want to simplify the code to not repeat myself for every object.

public ExampleObject GetExampleObject(string jsonString)
{
ExampleObject returnObject = new ExampleObject();
dynamic dynamicResult = JObject.Parse(jsonString);
if (!ReferenceEquals(dynamicResult.album, null))
   {
       //code block to extract to another method if possible
       returnObject.Id = dynamicResult.album.id; 
       returnObject.Name = dynamicResult.album.name;
       returnObject.Description = dynamicResult.albumsdescription;
       //etc..
   }
else if(!ReferenceEquals(dynamicResult.photo, null))
   {
       //duplicated here
       returnObject.Id = dynamicResult.photo.id;
       returnObject.Name = dynamicResult.photo.name;
       returnObject.Description = dynamicResult.photo.description;
       //etc..
   }
else if..
//etc..

return returnObject;
}

Is there any way I can extract the code blocks in the "if" statements to a separate method e.g:

private void ExampleObject GetExampleObject([string of desired type goes here? album/photo/etc])
{
  ExampleObject returnObject = new ExampleObject();
  returnObject.Id = dynamicResult.[something goes here?].id;
  returnObject.Name = dynamicResult.[something goes here?].name;
  //etc..
  return returnObject;
}

Is it even possible since we can't use reflection for dynamic objects. Or am I even using the JObject correctly?

Thanks.

dcdroid
  • 672
  • 2
  • 9
  • 29
  • 1
    Is the jsonString a string that is under your control? Or are you receiving this from another party and you need to communicate with it? – MichaelD Apr 19 '13 at 05:59
  • @MichaelD it's from another party. I'm just receiving and parsing. – dcdroid Apr 19 '13 at 13:05
  • More answers see [deserializing JSON to .net object using NewtonSoft (or linq to json maybe?)](http://stackoverflow.com/q/4749639) – Michael Freidgeim Jul 22 '16 at 07:55

3 Answers3

56

Assuming you're using the Newtonsoft.Json.Linq.JObject, you don't need to use dynamic. The JObject class can take a string indexer, just like a dictionary:

JObject myResult = GetMyResult();
returnObject.Id = myResult["string here"]["id"];

Hope this helps!

Connie Hilarides
  • 1,685
  • 15
  • 13
  • 10
    What goes in `["string here"]`? Wouldn't "id" just return the value of ID in the object? – joelforsyth Aug 31 '15 at 13:41
  • 1
    Is this case insensitive? – mardok Apr 07 '17 at 14:25
  • 2
    @joelforsyth, yes you might do, depending on the object structure, e.g. `returnObject.Id = (int)myResult["id"]; ` – Aaron Sep 13 '18 at 11:35
  • 1
    @mardok No, unfortunately it is case sensitive and so it may or may not work depending on the JsonSerializer settings that were used to serialize the object. – Iain May 14 '19 at 06:07
  • Wow! Thanks for the tip! I was trying to use GetProperty. For me I needed to apply it with a cast similar to this (but different type): String MyProperty1Value = (String)((Newtonsoft.Json.Linq.JObject)This.Tag)["MyProperty1"]; This just for an example, not my actual code. I was using a lambda fct. – John Foll Jul 26 '22 at 15:09
5

Another way of targeting this is by using SelectToken (Assuming that you're using Newtonsoft.Json):

JObject json = GetResponse();
var name = json.SelectToken("items[0].name");

For a full documentation: https://www.newtonsoft.com/json/help/html/SelectToken.htm

Ziad Akiki
  • 2,601
  • 2
  • 26
  • 41
0

with dynamic keyword like below:

private static JsonSerializerSettings jsonSettings;

private static T Deserialize<T>(string jsonData)
{
   return JsonConvert.DeserializeObject<T>(jsonData, jsonSettings);
}

//if you know what will return

var jresponse = Deserialize<SearchedData>(testJsonString);

//if you know return object type you should sign it with json attributes like

[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class SearchedData
{
    [JsonProperty(PropertyName = "Currency")]
    public string Currency { get; set; }
    [JsonProperty(PropertyName = "Routes")]
    public List<List<Route>> Routes { get; set; }
}

// if you don't know the return type use dynamic as generic type

var jresponse = Deserialize<dynamic>(testJsonString);
Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35