2

I have below JSON which I have de-serialized into a C# object and would like to extract the values of INFO_CARD_ID, DOCUMENT_NUM and REVISION_NM at each iteration.

{
    "result": {
        "message": "Successfully performed search",
        "columnlist": "INFO_CARD_ID,DOCUMENT_NUM,REVISION_NM,
        "recordcount": 2,
        "rows": [
            {
                "columns": [
                    {
                        "value": "UJ3P25HO3JBPLJZ2HU",
                        "key": "INFO_CARD_ID"
                    },
                    {
                        "value": "DOC1",
                        "key": "DOCUMENT_NUM"
                    },
                    {
                        "value": "05",
                        "key": "REVISION_NM"
                    }
                ]
            },
            {
                "columns": [
                    {
                        "value": "JWQ5TCIV4JC2BCQ4C5",
                        "key": "INFO_CARD_ID"
                    },
                    {
                        "value": "DOC2",
                        "key": "DOCUMENT_NUM"
                    },
                    {
                        "value": "05",
                        "key": "REVISION_NM"
                    }
                ]
            }
        ]
    }
}

Here are the C# classes:

    public class Columns
    {
        public string value { get; set; }
        public string key { get; set; }
    }

    public class Rows
    {
        public IList<Columns> columns { get; set; }
    }

    public class Result
    {
        public string message { get; set; }
        public string columnlist { get; set; }
        public int recordcount { get; set; }
        public IList<Rows> rows { get; set; }
    }

    public class searchOutputModel
    {
        public Result result { get; set; }
    }

So far, I have been trying to extract the information on a list with below expression but with no luck, as the individual value is getting stored on each iteration and not all the values at each iteration at the same time.

searchResponse = JsonConvert.DeserializeObject<searchOutputModel>(json);

var dynamicList = searchResponse.result.rows.SelectMany(x => x.columns).Where(y => y.key.Contains("INFO_CARD_ID") || y.key.Contains("DOCUMENT_NUM") || y.key.Contains("REVISION_NM")).Select(y => {
        dynamic myValue;
        if (y.key.Contains("INFO_CARD_ID"))
            myValue = new { INFO_CARD_ID = y.value };
        else if (y.key.Contains("DOCUMENT_NUM"))
            myValue = new { DOCUMENT_NUM = y.value };
        else
            myValue = new { REVISION_NM = y.value };
        return myValue;
    }).ToList();

Expected output:

INFO_CARD_ID       DOCUMENT_NUM  REVISION_NM
---------------------------------------------
UJ3P25HO3JBPLJZ2HU DOC1          05
JWQ5TCIV4JC2BCQ4C5 DOC2          05

I know I am doing wrong with iteration as it creates new list at each select, but I am not sure how can I achieve the solution that I am looking for. Any help is appreciated.

1
  • 1
    Don't use LINQ for this. Give your classes JsonProperty attributes so you can deserialize directly into your desired class structure. Commented Feb 25, 2021 at 19:39

2 Answers 2

1

We just need to select one object per row, no need for SelectMany here. Each property can be gotten by using columns.FirstOrDefault.

I would advise you to create a proper class for this rather than using dynamic but it makes little difference to the logic below.

Not sure why you used Contains on the column.key check, I've used ==

var dynamicList = searchResponse.result.rows.Select(r => 
    new {
        INFO_CARD_ID = r.columns.FirstOrDefault(c => c.key == "INFO_CARD_ID")?.value,
        DOCUMENT_NUM = r.columns.FirstOrDefault(c => c.key == "DOCUMENT_NUM")?.value,
        REVISION_NM = r.columns.FirstOrDefault(c => c.key == "REVISION_NM")?.value,
    }).ToList();
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @Charlieface, this one definitely answers my question. Cheers!
0

If you convert each Rows object to a Dictionary, you can use the Dictionary to create objects:

var ans = searchResponse.result.rows
            .Select(r => r.columns.ToDictionary(c => c.key, c => c.value))
            .Select(cd => new {
                INFO_CARD_ID = cd["INFO_CARD_ID"],
                DOCUMENT_NUM = cd["DOCUMENT_NUM"],
                REVISION_NM = cd["REVISION_NM"]
            });

1 Comment

Thank you @NetMage for your solution as well :)

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.