1

JSON

{
  "count": 3,
  "value": [
    {
      "id": "AAAAAAAAAAAAA",
      "description": "test1",
      "name": "name1"
    },
    {
      "id": "BBBBBBBBBB",
      "description": "test2",
      "name": "name2"
    },
    {
      "id": "CCCCCCCCCCCC",
      "description": "test3",
      "name": "name3"
    }
  ]
}

I have a code in my solution retrieving from a LIST api and giving the JSON above. How can I use a LINQ to retrieve specific values? (e.g) I need to select name1 and I will get the id,description,name values.

I am using a dynamic variable in my code:

dynamic json = JObject.Parse(client.GetString().Result);

I'd been tinkering with other online guides the past few hours. However, can't get the result right.

Please help.

5
  • 1
    why are you using dynamic here ? Since you already know the structure of your JSON, then you should create a Type for it. Commented Oct 3, 2018 at 9:27
  • im using dynamic for shorter code lines and using core. But im still new to this. I'll only use the values once, CMIIW so I think its not good to make another object? Commented Oct 3, 2018 at 9:29
  • 2
    I've never seen anyone using dynamic for shorter code lines Commented Oct 3, 2018 at 9:30
  • @Hexxed : yes you should not use dynamic in this case, and create a proper type here. With a strongly typed language like C#, that's the way to go. The rationale behind adding dynamic in the language was to allow calls that could return non-determined structures / types, for instance calls to external DLL / COM things. You want to use it only if you are really stuck otherwise. Commented Oct 3, 2018 at 9:38
  • 1
    I do agree with @Pac0, there's no need to use dynamics here, given that you already know the structure of the json string. Don't use dynamics unless you have a very good reason to do it. Check Advantages and Disadvantages of C# 4.0 'dynamic' keyword? Commented Oct 3, 2018 at 9:43

4 Answers 4

4

One solution would be to deserialize your JSON string into C# objects and then use Linq to get a specific object.

C# class definitions:

public class Content
{
    [JsonProperty("count")]
    public int Count { get; set; }

    [JsonProperty("value")]
    public List<Value> Values { get; set; }

    public Content()
    {
        Values = new List<Value>();
    }
}

public class Value
{
    [JsonProperty("id")]
    public string Id { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }
}

Deserializing and getting the object:

string json = @"{
""count"": 3,
""value"": [
  {
    ""id"": ""AAAAAAAAAAAAA"",
    ""description"": ""test1"",
    ""name"": ""name1""
  },
  {
    ""id"": ""BBBBBBBBBB"",
    ""description"": ""test2"",
    ""name"": ""name2""
  },
  {
    ""id"": ""CCCCCCCCCCCC"",
    ""description"": ""test3"",
    ""name"": ""name3""
  }
]
}";


Content content = JsonConvert.DeserializeObject<Content>(json);

Value value = content.Values.FirstOrDefault(x => x.Name.Equals("name1", StringComparison.InvariantCultureIgnoreCase));
Sign up to request clarification or add additional context in comments.

3 Comments

this will work like a charm, however I only using the JSON value once and dispose of it. is making C# objects more efficient than using other dynamic solutions?
@Hexxed I don't know which solution is the most performant, you'd need to run some benchmarks to check that. For such a simple json string I'd say it won't make much difference
@Hexxed - is making C# objects more efficient than using other dynamic solutions? - stackify.com/top-11-json-performance-usage-tips suggests to Use pre-defined typed classes for faster performance. That being said, see also ericlippert.com/2012/12/17/performance-rant See also How does having a dynamic variable affect performance? which indicates that using dynamic always has a performance penalty, which possibly might be small.
2

First, you can create a class to represent a client:

public class Client
{
    public string Id { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }
}

With this class, you can use JObject.Parse (as you're already doing) to parse the JSON into something that can be queried, use SelectToken to pull out the value array and then use ToObject to convert that to a list of Clients. Here's what that looks like:

var jsonObject = JObject.Parse(json_source);
var jsonObjectValue = jsonObject.SelectToken("value");
var clients = jsonObjectValue.ToObject<List<Client>>();

Once you've got your clients variable, you can use a simple LINQ statement to find the one that is name1:

var clientWithName1 = clients.SingleOrDefault(x => x.Name == "name1");

In this case, clientWithName will be null if no such client was found.

Here's a dotnetfiddle that demonstrates a complete solution.

2 Comments

I like this solution more. Just to add my two cents: jsonObject["value"] is a JArray already, so we can save a variable, and turns out to this: var jsonObject = JObject.Parse(json_source); var clients = (jsonObject["value"]).ToObject<List<Client>>();
Thanks for the input, @WalterAgile. You could even go as far as this: var clients = JObject.Parse(json_source)["value"].ToObject<List<Client>>();. :)
1

Create an object Client that has properties id, description and name. Deserialize the json into a list of these objects.

List<Client> clients = JsonConvert.Deserialize<List<Client>>(json_source);
string desc = clients[0].description;

3 Comments

And then clients.First[OrDefault](c => c.name == "name1");
@KirkLarkin that's right, it should be an object with a list of Clients as written in RuiJarimba's answer. Still, the idea to deserialize to a proper type instead of dynamic is what makes it easier to use Linq afterwards
This is not the right answer - you cannot assume that the object with name1 will be always the first one in the array, you need to query the deserialized array, as already mentioned by @Rafalon
-1

Apparently with fiddling with my code I found an answer for myself. Thanks for to the ones trying to help me for giving me ideas.

var requestWorkProcess = await client.GetStringAsync("my url");
var workProcessId = JObject.Parse(requestWorkProcess)["value"].Children<JObject>().FirstOrDefault(o => o["name"].ToString() == workProcess).GetValue("id");

1 Comment

Not a downvoter, but this answer would not be the recommended way. It seems you are using everything in your power to circumvent any type safety provided by the language.

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.