bin
bin

Reputation: 550

JSON String to DataTable Object in C#

So basically I SEARCHED everywhere, and I'm not finding anything that works in my situation.

I'm working with an API for Overwatch (a game) and I want to turn a String I download from the web, and check if it has a JSON string.

Let me show you the code:

 < !--language: c# -->
                HttpClient dc = new HttpClient();
                string tag = e.Message.Text.ToString().Substring(7).Replace("#", "-");
                string apiurl = (@"http://api.lootbox.eu/" + "pc/" + "global/" + tag + "/profile");
                HttpResponseMessage datares = await dc.GetAsync(apiurl);
                string finaldata = await datares.Content.ReadAsStringAsync();
                #region PC
                if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "pc/" + "us/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();

                }
               else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "pc/" + "kr/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "pc/" + "eu/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "pc/" + "cn/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                #endregion
                #region XBOX LIVE
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "xbl/" + "us/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "xbl/" + "eu/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "xbl/" + "kr/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "xbl/" + "cn/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "xbl/" + "global/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                #endregion
                #region PSN
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "psn/" + "us/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "psn/" + "global/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "psn/" + "cn/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "psn/" + "eu/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                else if (finaldata.Contains(":404"))
                {
                    apiurl = (@"http://api.lootbox.eu/" + "psn/" + "kr/" + tag + "/profile");
                    datares = await dc.GetAsync(apiurl);
                    finaldata = await datares.Content.ReadAsStringAsync();
                }
                #endregion

                DataTable obj = JsonConvert.DeserializeObject(finaldata);

So an example output, in this case, wouldv'e been:

{"data":{"username":"Rezoh","level":305,"games":{"quick":{"wins":"378"},"competitive":{"wins":"82","lost":85,"played":"167"}},"playtime":{"quick":"88 hours","competitive":"36 hours"},"avatar":"https://blzgdapipro-a.akamaihd.net/game/unlocks/0x0250000000000D70.png","competitive":{"rank":"3392","rank_img":"https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-5.png"},"levelFrame":"https://blzgdapipro-a.akamaihd.net/game/playerlevelrewards/0x025000000000092D_Border.png","star":"https://blzgdapipro-a.akamaihd.net/game/playerlevelrewards/0x025000000000092D_Rank.png"}}

Now I need to convert that to a table of some sort or something.

I got the JSON.Net but most people said to setup a class BEFORE you convert,

Problem was that: I had 2 "wins": and 3 "competitive": as you can see in the JSON string.

So making a class wasn't possible to my belief in this case. I tried making a new DataTable as shown in the last line of code but it tells me "Cannot implicitly convert type object to System.Data.DataTable" when using JsonConvert.DeserializeObject(finaldata); I even tried doing .ToString(); and also the dates variable, and .ToString() in that too.

I need a proper way to show these stats so, for example, I can show:

"Stats for user " + obj.Name + ":"
"Wins: " + obj.Wins
"Losses: " + obj.Losses
"Rank: " + obj.Rank

And no solutions online help me in my situation.

EDIT:

This solution doesn't work either for me:

convert json String to datatable? or this Nested Json String to DataTable

Nor does this:

  var token = JToken.Parse(finaldata);

                if (token.Type == JTokenType.Object)
                    token = new JArray(token);

                var a = token.ToObject<DataTable>();

Upvotes: 1

Views: 2468

Answers (1)

aloisdg
aloisdg

Reputation: 23521

You can use a class as they said. I used http://json2csharp.com/ but VS can do it too.

You can try it here: https://dotnetfiddle.net/iaIvOn

using System;
using Newtonsoft.Json;

public class Program
{
    public void Main()
    {
        var json = @"{""data"":{""username"":""Rezoh"",""level"":305,""games"":{""quick"":{""wins"":""378""},""competitive"":{""wins"":""82"",""lost"":85,""played"":""167""}},""playtime"":{""quick"":""88 hours"",""competitive"":""36 hours""},""avatar"":""https://blzgdapipro-a.akamaihd.net/game/unlocks/0x0250000000000D70.png"",""competitive"":{""rank"":""3392"",""rank_img"":""https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-5.png""},""levelFrame"":""https://blzgdapipro-a.akamaihd.net/game/playerlevelrewards/0x025000000000092D_Border.png"",""star"":""https://blzgdapipro-a.akamaihd.net/game/playerlevelrewards/0x025000000000092D_Rank.png""}}";

        // read the doc: http://www.newtonsoft.com/json
        var rootObject = JsonConvert.DeserializeObject<RootObject>(json);

        Console.WriteLine("Stats for user " + rootObject.Data.Username + ":");
        Console.WriteLine("Wins: " + rootObject.Data.Games.Competitive.Wins);
        Console.WriteLine("Losses: " + rootObject.Data.Games.Competitive.Lost);
        Console.WriteLine("Rank: " + rootObject.Data.Competitive.Rank);
    }

    public class Quick
    {
        // Free case support!
        public string Wins { get; set; }
    }

    public class Competitive
    {
        public string Wins { get; set; }  // you may want to check this string here ;)
        public int Lost { get; set; }
        public string Played { get; set; }
    }

    public class Games
    {
        public Quick Quick { get; set; }
        public Competitive Competitive { get; set; }
    }

    public class Playtime
    {
        public string Quick { get; set; }
        public string Competitive { get; set; }
    }

    public class Competitive2
    {
        public string Rank { get; set; }
        // attribute ftw! http://www.newtonsoft.com/json/help/html/SerializationAttributes.htm
        [JsonProperty(PropertyName = "rank_img")]
        public string RankImg { get; set; }
    }

    public class Data
    {
        public string Username { get; set; }
        public int Level { get; set; }
        public Games Games { get; set; }
        public Playtime Playtime { get; set; }
        public string Avatar { get; set; }
        public Competitive2 Competitive { get; set; }
        public string LevelFrame { get; set; }
        public string Star { get; set; }
    }

    public class RootObject
    {
        public Data Data { get; set; }
    }
}

output

Stats for user Rezoh:
Wins: 82
Losses: 85
Rank: 3392

If Quick and Competitive are Game, maybe:

public abstract class Game
{
    public string Wins { get; set; } // you may want to check this string here ;)
    public int Lost { get; set; }
    public string Played { get; set; }
}

public class Quick : Game // note that Quick game has Lost and PLayed now!
{
}

public class Competitive : Game
{
}

Or even (as @EpicSam proposed in comment):

public class Game
{
    public string Wins { get; set; } // you may want to check this string here ;)
    public int Lost { get; set; }
    public string Played { get; set; }
}

public class Games
{
    public Game Quick { get; set; }
    public Game Competitive { get; set; }
}

Upvotes: 1

Related Questions