Home > other >  Parse Json object into an list<string>
Parse Json object into an list<string>

Time:09-08

I have a result set in Json format

{"optouts":[{"date":"2022-08-31","number":"12818300000"},{"date":"2022-08-29","number":"18324930000"},{"date":"2022-08-19","number":"16822520000"}],"offset":1,"limit":20,"total":3}

I would like to fetch only numbers and add them to an array/list.

public override async Task<OptOutNumbers> GetOptOuts(string phoneNumber, string limit)
        {
            var uri = "/v2/opt-outs";
            try
            {
                var dto = new SmsGlobalGetOptOutsDTO()
                {
                    limit = 1000
                };

                optOutNumbers.RequestPayload = dto;
                var response = await GetOptOutsNumbers(uri, HttpMethod.Get, dto);
                var result = response.Content.ReadAsStringAsync().Result;
                var a = JObject.Parse(result);
                List<string> blockedNumbers = new List<string>();
                foreach (JObject o in a.Children<JObject>())
                {
                    foreach (JProperty p in o.Properties())
                    {
                        string name = p.Name;
                        string number = (string)p.Value;
                        blockedNumbers.Add(number);
                    }
                }
            }
            catch(Exception ex)
            {
                Response.HasError = true;
                Response.ResponseMessage = ex.Message;
            }
            return optOutNumbers;
        }
The above code did not work for me. It's not going inside the foreach loop

CodePudding user response:

just parse your json

List<string> numbers = JObject.Parse(result)["optouts"]
                                    .Select(x => (string)x["number"]).ToList();

CodePudding user response:

Instead of parsing the JSON, you can model two simple classes, deserialize (JsonConvert.DeserializeObject) the response to an Optouts object and run a simple Select:

void Main()
{
    var input = new Optouts {
        optouts = new List<Optout> {
            new Optout { number = "12345"},
            new Optout { number = "678"},
            new Optout { number = "90"},
        }
    };
    List<string> blockedNumbers = input.optouts.Select(o => o.number).ToList();
}

public class Optout
{
    public string date { get; set; }
    public string number { get; set; }
}

public class Optouts
{
    public List<Optout> optouts { get; set; }
    public int offset { get; set; }
    public int limit { get; set; }
    public int total { get; set; }
}

CodePudding user response:

Your current implementation is failing because the top-level token is an object with a property that has an array value, not an array in and of itself.

You need to first retrieve the optouts property and then iterate it in turn to get each child object, filtering the properties to your "number" property:

var a = JObject.Parse(result);
List<string> blockedNumbers = new List<string>();
foreach (JObject o in a["optouts"])
{
    foreach (JProperty p in o.Properties()).Where(x => x.Name == "number"))
    {
        string name = p.Name;
        string number = (string)p.Value;
        blockedNumbers.Add(number);
    }
}

This results in blockedNumbers containing

12818300000
18324930000
16822520000

as expected.

  • Related