Parsowanie zagnieżdżonego JSON

0

Witam.
Na wstępie, jestem bardzo początkujący i proszę nie linczować. ;p

Do rzeczy.

Model - SteamIdModel.cs

using System.Collections.Generic;

namespace SteamIDFinder.Models
{
    public class RootObject
    {
        public ResponseObject response { get; set; }
    }

    public class ResponseObject
    {
        public List<Player> players { get; set; }
    }

    public class Player
    {
        public string steamid { get; set; }
        public int communityvisibilitystate { get; set; }
        public int profilestate { get; set; }
        public string personaname { get; set; }
        public int commentpermission { get; set; }
        public string profileurl { get; set; }
        public string avatar { get; set; }
        public string avatarmedium { get; set; }
        public string avatarfull { get; set; }
        public string avatarhash { get; set; }
        public int lastlogoff { get; set; }
        public int personastate { get; set; }
        public string primaryclanid { get; set; }
        public int timecreated { get; set; }
        public int personastateflags { get; set; }
    }
}

Controller - SteamIdController.cs

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SteamIDFinder.Models;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.Json;


namespace SteamIDFinder.Controllers
{
    public class SteamIdController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost, ValidateAntiForgeryToken]
        public IActionResult Index(string GetSteamId)
        {
            const string API_KEY = "AF9B93E6758E6506DA299B2FDA6CA3DE";
            const string MojSID = "76561198978527815";
            //string SteamId64 = GetSteamId;
            string API_link = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" + API_KEY + "&format=json&steamids=" + MojSID;

            WebClient client = new WebClient();
            string reply = client.DownloadString(API_link);
            //var r = JsonConvert.DeserializeObject<RootObject>(reply);

            var jObject = JObject.Parse(reply);

            if (jObject != null)
            {
                
                var players = jObject["players"];
                string test2 = players["personaname"].ToString();
            }

            return View();
        }
    }
}

A tak prezentuje się finalnie JSON

{
    "response": {
        "players": [
            {
                "steamid": "76561198978527815",
                "communityvisibilitystate": 3,
                "profilestate": 1,
                "personaname": "Luvv",
                "commentpermission": 1,
                "profileurl": "https://steamcommunity.com/id/elomelotupaulinka/",
                "avatar": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/78/789fdb09abc205dacd5457c013643a94e1b5330a.jpg",
                "avatarmedium": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/78/789fdb09abc205dacd5457c013643a94e1b5330a_medium.jpg",
                "avatarfull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/78/789fdb09abc205dacd5457c013643a94e1b5330a_full.jpg",
                "avatarhash": "789fdb09abc205dacd5457c013643a94e1b5330a",
                "personastate": 1,
                "realname": "Paulina",
                "primaryclanid": "103582791470021249",
                "timecreated": 1563652881,
                "personastateflags": 0,
                "gameextrainfo": "Counter-Strike: Global Offensive",
                "gameid": "730",
                "loccountrycode": "PL",
                "locstatecode": "52",
                "loccityid": 35957
            }
        ]
    }
}

Chciałbym uzyskać dostęp do wszystkich wartości w tablicy players (np. profilestate, profileurl itp...)
Cały dzień siedzę nad tym problemem i próbuję go rozwiązać przekopując pół stackoverflowa, lecz bez skutku.

1

Żeby dostać się do players najpierw musisz odnieść się do response czyli:

var players = jObject[response][players]
1

Zrób klasę o nazwie response. W niej umieść listę o nazwie Players zawierające obiekty z tymi właściwościami o identycznych nazwach. Zdeserializuj wtedy to i będzie działać

0

@cebilon123:
Wykonuję zapytanie ze zmiennej API_link - tak wygląda sklejony link [http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=AF9B93E6758E6506DA299B2FDA6CA3DE&format=json&steamids=76561198978527815]
W rezultacie otrzymuje JSON, którego pokazałem w powyższym poście. Problem mój polega na tym, że nie wiem w jaki sposób pobrać wszystkie wartości z tablicy player by potem móc później wyświetlić to w HTMLu

Zgadza się, wywala mi taki błąd:
Error CS1579 foreach statement cannot operate on variables of type 'RootObject' because 'RootObject' does not contain a public instance or extension definition for 'GetEnumerator'

A tak wygląda kod przy tym błędzie:

[HttpPost, ValidateAntiForgeryToken]
        public IActionResult Index(string GetSteamId)
        {
            const string API_KEY = "AF9B93E6758E6506DA299B2FDA6CA3DE";
            const string MojSID = "76561198978527815";
            //string SteamId64 = GetSteamId;
            string API_link = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" + API_KEY + "&format=json&steamids=" + MojSID;

            WebClient client = new WebClient();
            string reply = client.DownloadString(API_link);
            var r = JsonConvert.DeserializeObject<RootObject>(reply);

            string test;

            foreach (var player in r)
            {
                ViewBag.Test = string.Format("{0}", player.personaname);
                test = ViewBag.Test;
            }
            return View();
        }
1

Już Ci odpowiedziałem i kolega przede mną w jaki sposób

1

Przecież w linii masz swoją odpowiedź, ale ją zakomentowałeś :D

//var r = JsonConvert.DeserializeObject<RootObject>(reply);

W ten sposób też możesz tylko zauważ, że w jObject odnosisz się do właściwości players a tam go nie ma.

             var jObject = JObject.Parse(reply);
 
             if (jObject != null)
             {
 
                 var players = jObject["players"];
                 string test2 = players["personaname"].ToString();
             }

To powinno być coś takiego:

var player = jObject["response"]["players"][0]

Zawsze możesz debuggerem podejrzeć sobie jak wygląda struktura.

0
wielki_bebzon napisał(a):

To powinno być coś takiego:

var player = jObject["response"]["players"][0]

Dzięki wielkie, udało się. :)

A możesz mi powiedzieć w jaki sposób można dostać się do tablicy players poprzez tą metodę? [var r = JsonConvert.DeserializeObject<RootObject>(reply);]

I który sposób parsowania z tych dwóch jest najwydajniejszy?

1

Ja to zawsze robię w taki sposób:

class Program
    {
        static void Main(string[] args)
        {
            string json = "...";
            var obj = response.FromJson(json);
        }
    }
    public class player
    {
        public int steamid { get; set; }
        public int communityvisibilitystate { get; set; }
        public int profilestate { get; set; }
        public string personaname { get; set; }
        public int commentpermission { get; set; }
        public string profileurl { get; set; }
        public string avatarmedium { get; set; }
        public string avatarfull { get; set; }
        public string avatarhash { get; set; }
        public bool personastate { get; set; }
        public string realname { get; set; }
        public string primaryclanid { get; set; }
        public int timecreated { get; set; }
        public bool personastateflags { get; set; }
        public string gameextrainfo { get; set; }
        public int gameid { get; set; }
        public string loccountrycode { get; set; }
        public int locstatecode { get; set; }
        public int loccityid { get; set; }
    }
    public class response
    {
        public List<player> players = new List<player>();
        public static response FromJson(string json)
        {
            return JsonConvert.DeserializeObject<response>(json);
        }
    }
2
Captain Jack napisał(a):
wielki_bebzon napisał(a):

To powinno być coś takiego:

var player = jObject["response"]["players"][0]

Dzięki wielkie, udało się. :)

A możesz mi powiedzieć w jaki sposób można dostać się do tablicy players poprzez tą metodę? [var r = JsonConvert.DeserializeObject<RootObject>(reply);]

Korzystasz z visual studio (wtedy vs podpowiada strukturę)?
W r.response masz listę players tam możesz sobie wyfiltrować i znaleźć konkretnego playera za pomocą linq (SingleOrDefault, FirstOrDefault).

I który sposób parsowania z tych dwóch jest najwydajniejszy?

Wydaje mi się (ale bez testów nie ma co zgadywać), że nie ma to różnicy tylko korzystając z JsonConvert od razu deserializujesz do konkretnego typu.

0

@wielki_bebzon: Faktycznie to działa! Szczerze to nigdy bym nie wpadł na to. :P
Dziękuję wszystkim za pomoc!

1 użytkowników online, w tym zalogowanych: 0, gości: 1