zackmark15
zackmark15

Reputation: 727

JSON Parsing check if value exists in the array

I'm new and just learning parsing with JSON

I'm checking if value exists in the array. my code is worked but I just wanna ask the shortest code or improvement for this?

this is what I'm getting: m3u8 It's randomely exists from array [0] to [4]. so I tried .contains method.

  public static async Task<string> GetInfoAsync(string url)
    {
        var resource = await GetWebSourceAsync(url);
        JObject jObject = JObject.Parse(resource);

        var m3u8 = string.Empty;

        if (jObject["data"]["program"]["video"][0].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][0]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][1].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][1]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][2].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][2]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][3].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][3]["m3u8"].Value<string>();
        }
        else if (jObject["data"]["program"]["video"][4].Value<string>().Contains("#EXTM3U"))
        {
            m3u8 = jObject["data"]["program"]["video"][4]["m3u8"].Value<string>();
        }

        return m3u8;
    }

Here's the structures of JSON

Upvotes: 1

Views: 1245

Answers (3)

zackmark15
zackmark15

Reputation: 727

Alright this is the solution by @Volodymyr Thank you so much.

  public static async Task<string> GetInfoAsync(string url, EpisodeInfo info)
    {
        var resource = await GetWebSourceAsync(url);

        JObject jObject = JObject.Parse(resource);
        return jObject["data"]["program"]["video"]
            .Where(i => i.ToString().Contains("#EXTM3U"))
            .FirstOrDefault()
            ?["m3u8"].ToString();
    }

and Here's the solution by @dbvega Thanks too.

   public static async Task<string> GetWebSourceAsync(string url)
    {
        var handler = new HttpClientHandler
        {
            Proxy = null,
            UseProxy = false
        };

        using (var client = new HttpClient(handler))
        {
            client.DefaultRequestHeaders.Add("Method", "GET");
            client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36");

            using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
            {
                response.EnsureSuccessStatusCode();
                string json = await response.Content.ReadAsStringAsync();
                var obj = JsonConvert.DeserializeObject<Rootobject>(json);
                var result = obj?.data?.program?.video?.FirstOrDefault(v => v.m3u8?.Contains("#EXTM3U") == true);
                return JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.Indented);
            }
        }
    }

Upvotes: 0

denys-vega
denys-vega

Reputation: 3697

Assuming your json text be similar to (it may have much more data, it does not matter):

{
    "data": {
        "program": {
            "video": [
                {
                    "m3u8Url": "http://go.to/video1",
                    "vid": "",
                    "rp": 0 
                },
                {
                    "m3u8Url": "http://go.to/video2",
                    "m3u8": "#EXTM3U #EXT-X-TARGET...",
                    "vid": "",
                    "rp": 0
                },
                {
                    "m3u8Url": "http://go.to/video3",
                    "vid": "",
                    "rp": 0
                }
            ]
        }
    }
}

You can retrieve the first video containing #EXTM3U using the following code:

var anonymousObj = new
{
    data = new
    {
        program = new
        {
            video = new[]
            {
                new
                {
                    m3u8Url = "",
                    m3u8 = "",
                    vid = "",
                    rp = 0
                }
            }
        }
    }
};
var obj = JsonConvert.DeserializeAnonymousType(json, anonymousObj);
var video = obj?.data?.program?.video?.FirstOrDefault(v => v.m3u8?.Contains("#EXTM3U") == true);

Other solution, if you're using visual studio, you can map any JSON text to class using the editor. Go to Edit -> Paste Special -> Paste JSON as Classes. The output for example JSON will be:

public class Rootobject
{
    public Data data { get; set; }
}

public class Data
{
    public Program program { get; set; }
}

public class Program
{
    public Video[] video { get; set; }
}

public class Video
{
    public string m3u8Url { get; set; }
    public string vid { get; set; }
    public int rp { get; set; }
    public string m3u8 { get; set; }
    //it will have other props
}

Then you can use the JsonConvert and deserialize to Rootobject type.

var obj2 = JsonConvert.DeserializeObject<Rootobject>(json);
var video2 = obj2?.data?.program?.video?.FirstOrDefault(v => v.m3u8?.Contains("#EXTM3U") == true);

Upvotes: 2

Volodymyr Vedmedera
Volodymyr Vedmedera

Reputation: 114

You could use LINQ to your advantage:

JObject jObject = new JObject();
var m3u = jObject["data"]["program"]["video"]
    .Where(i => i.Value<string>().Contains("#EXTM3U"))
    .FirstOrDefault()
    ?["m3u8"].Value<string>();

Let me know if it doesn't help.

Upvotes: 2

Related Questions