Nithya
Nithya

Reputation: 782

Select object based on condition inside a nested array

I have a Jarray of response and inside Jarray there is an array of Clients and based on the condition I need to select the object in Array Json is

JArray response = JArray.Parse(@"[
                  {
                    'ProviderTransactionID': '4c4c5b43-0dd6-490c-9a59-062e25c04019',
                     'IsSuccess': 'False',
                     'ErrorMessages': 'Some error',
                      'ClientInfo': [
                       {
                         'InternalID': '98367',
                         'UniqueID': '',
                         'ErrorMessages': 'ERROR:'
                       },
                       {
                         'InternalID': '98368',
                         'UniqueID': '',
                         'ErrorMessages': 'ERROR:'
                       }
                     ]
                   }
            ]");

For example, I need to select the ClientInfo Object where InternalID=98367

But

response.SelectToken("ClientInfo") returning null

response.SelectToken("ClientInfo") as JArray returning null

response.SelectTokens("ClientInfo") not returning any result

response.Children().Where(lst=>lst.SelectToken("ClientInfo").HasValues) is throwing Arg_PlatformNotSupported exception

response.SelectTokens("ClientInfo").Where(lst=>lst.Value<int>()==98367).FirstOrDefault() is returning null

can anyone please help me with how to get all ClientInfo object matching ID in an array of responses?

Upvotes: 0

Views: 1895

Answers (3)

Amogh Sharma
Amogh Sharma

Reputation: 1

You can query JSON with LINQ as below:

var Result = (from p in response
                           select new
                           {
                               Errors = (from z in p["ClientInfo"]
                                         where (string)z["InternalID"] == "98368"
                                         select new
                                         {
                                             InternalID = (string)z["InternalID"],
                                             UniqueID = (string)z["UniqueID"],
                                             ErrorMessages = (string)z["ErrorMessages"],
                                         }).ToList()

                           }).ToList();

we can use anonymous type .net will create class intrenally. if you want to use Parent data element also say ProviderTransactionID below code will work for that also

        var Result = (from p in response
                           select  (from z in p["ClientInfo"]
                                         where (int)z["InternalID"] == 98368
                                         select new
                                         {
                                             ProviderTransactionID = (string)p["ProviderTransactionID"],
                                             InternalID = (int)z["InternalID"],
                                             UniqueID = (string)z["UniqueID"],
                                             ErrorMessages = (string)z["ErrorMessages"],
                                         }
                                         ).ToList()

                           ).ToList();

Upvotes: 0

tcconstantin
tcconstantin

Reputation: 389

Based on the documentation (https://www.newtonsoft.com/json/help/html/SelectToken.htm) a possible solution can be:

response.SelectTokens("$..ClientInfo[?(@.InternalID=='98367')]").ToList();

Upvotes: 6

Chris
Chris

Reputation: 3293

If you don't want to use a class then you need something like this:

JArray jArray = JArray.Parse("[\r\n                  {\r\n                    'ProviderTransactionID': '4c4c5b43-0dd6-490c-9a59-062e25c04019',\r\n                     'IsSuccess': 'False',\r\n                     'ErrorMessages': 'Some error',\r\n                      'ClientInfo': [\r\n                       {\r\n                         'InternalID': '98367',\r\n                         'UniqueID': '',\r\n                         'ErrorMessages': 'ERROR:'\r\n                       },\r\n                       {\r\n                         'InternalID': '98368',\r\n                         'UniqueID': '',\r\n                         'ErrorMessages': 'ERROR:'\r\n                       }\r\n                     ]\r\n                   }\r\n            ]");

const string internalId = "98367";

foreach (JToken obj in jArray)
{
    IEnumerable<JToken> clientInfoObjects = obj.SelectToken("ClientInfo").Where(clientInfoJToken => clientInfoJToken["InternalID"].Value<string>() == internalId);
}

So because you are parsing into a JArray you need to iterate through the objects (although only one in your case).

Then you are at your object level so you can use .SelectToken("ClientInfo") which gives you a JToken (JArray) enabling you to use .Where() to filter the objects to your requirements.

The result is an IEnumerable<JToken> which will be the ClientInfo objects with the id you specify.

Upvotes: 1

Related Questions