1

Hello Everyone and thanks for looking at this. I'm relatively new to vb.net and extremely new to parsing json in vb. I am using JSON.Net and I'm looking to gather data from the following JSON.

http://hastebin.com/bagiyetece.apache

I have classes created for each of the "sections". I am unsure of the correct terminology.

Class One:

Public Class StatsWrapper
    Public SummonerID as Long
    Public PlayerStatSummaries as playerStatSummaryTypeWrapper
End Class

Class Two:

Public Class playerStatSummaryTypeWrapper
    Public playerStatSummaryType As String
    Public wins As Long
    Public modifyDate As Long
    Public aggregatedStats As aggregatedStatsWrapper
End Class

Class Three:

http://hastebin.com/qopanafabe.php

My end goal is to be able to get elements like "totalChampionKills" for the playerStatSummaryType of "Cap5x5" and insert them into a datagridview.

I've been able to correctly parse the following JSON simply by using JObject.Parse.

{"UserName":{"id":84737282,"name":"UserName","profileIconId":660,"summonerLevel":30,"revisionDate":1455686689000}}

To get the id object, I would use:

Dim JSONDerulo = JObject.Parse(JSONResponse)
Dim SummonerID = JSONDerulo(LCase(ToolStripTextBox1.Text))("id")

Where the ToolStripTextBox1.Text is the UserName.

When I try to apply the same logic as above to the larger JSON file in a different sub:

Dim JSONDerulo = JObject.Parse(JSONResponse)
Dim PlayerStatSummaries = JSONDerulo("playerStatSummaries")
Dim Jarray As JArray = PlayerStatSummaries

I can do something like:

For Each obj As JObject In Jarray
    TextBox2.Text = TextBox2.Text + Environment.NewLine + obj.ToString + Environment.NewLine
Next

Or call Jarray(1) and parse that again but the list of game types is going to be different for each UserName. I do have a master list for every game type though:

AramUnranked5x5, Ascension, Bilgewater, CAP5x5, CoopVsAI, CoopVsAI3x3, CounterPick, FirstBlood1x1, FirstBlood2x2, Hexakill, KingPoro, NightmareBot, OdinUnranked, OneForAll5x5, RankedPremade3x3, RankedPremade5x5, RankedSolo5x5, RankedTeam3x3, RankedTeam5x5, SummonersRift6x6, Unranked, Unranked3x3, URF, URFBots

If I want to (for example) call AramUnranked5x5.TotalChampionKills or something similar would I have to create a class for each type?

Any suggestions or ideas?

Thanks Again

  • You dont usually need classes if you parse the json, those are used to deserialize back into object(s). The classes are mostly right - `playerStatSummaryTypeWrapper` should have a `Property losses As Integer`. You dont need a DGV for one object, a PropertyGrid *might* be a better choice – Ňɏssa Pøngjǣrdenlarp Feb 19 '16 at 00:05
  • Would I be able to use a for loop to deserialize each item in Jarray to a playerStatSummaryTypeWrapper? – Joseph Schmitt Feb 19 '16 at 00:36
  • Yes (the top class is slightly off that is an array so `PlayerStatSummaries as playerStatSummaryTypeWrapper()`. OR deserialize all of them to an array of `playerStatSummaryTypeWrapper` maybe this: http://stackoverflow.com/q/31084143 will help – Ňɏssa Pøngjǣrdenlarp Feb 19 '16 at 00:42

1 Answers1

0

Note: the json posted is considerably shorter and simpler than the gruesome aggregatedStatsWrapper class linked to depicts! Without data, I cant say whether it is right or not.

Since the aggregatedStats is its own type, nothing very interesting will show for it in a DataGridView, just the type name. There are several ways to handle this. One is to hide the property from the DGV, then when they change selected/current rows, find the new one in the list and set player.aggregatedStats as the selected object in a property grid for a master-detail type view. Playerstatsummary:

Public Class Playerstatsummary
    Public Property playerStatSummaryType As String
    Public Property wins As Integer
    Public Property modifyDate As Long
    <Browsable(False)>
    Public Property aggregatedStats As Aggregatedstats
    Public Property losses As Integer
End Class

<Browsable(False)> will result in the TypeName not being shown in a DGV:

Dim jstr = File.ReadAllText("C:\Temp\myjsonfilename")

Dim jobj = JObject.Parse(jstr)
Dim players = JsonConvert.DeserializeObject(Of List(Of Playerstatsummary))(jobj("playerStatSummaries").ToString)

By Parsing it first, you can skip that outer container. jobj("playerStatSummaries").ToString passes the property data to be deserialized into a List.

You can display what you have very easily without having to loop at all:

dgv1.DataSource = players

It wont yet know about Aggregatedstats unless and until you work out that class exactly. Until then, the type name will display. The post mentions being interested in Cap5x5 only. In that case, a PropertyGrid might be a better UI mechanism (after you find that guy in the list). Result:

enter image description hereenter image description here

(This is from before I added <Browsable(False)> to the class). You could show aggregatedStats as detail like this:

Private Sub DataGridView1_SelectionChanged(...etc
    If DataGridView1.SelectedRows.Count = 0 Then Return

    Dim thisOne = DataGridView1.SelectedRows(0).Cells(0).Value.ToString

    Dim player = players.FirstOrDefault(Function(f) f.playerStatSummaryType = thisOne)
    If player IsNot Nothing Then
        PropertyGrid1.SelectedObject = player.aggregatedStats
    End If
End Sub

In case you are wondering, the date is almost certainly a Unix Epoch date, easily converted to .NET.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • Thanks so much Plutonix! Do you know of any books/other resources I can read to learn more about vb.net other than simply googling issues as I come across them? – Joseph Schmitt Feb 20 '16 at 02:39
  • If this answers the question, please click the checkmark next to the answer. Soon (at 15 rep) you will be able to upvote which you should do for any Q or A which informs, educates, amazes or amuses you. This helps others find good answers. For learning, I favor MSDN. The articles can be dense but they *are* comprehensive and authoritative. They and the demo code can often at least help you frame the question better, – Ňɏssa Pøngjǣrdenlarp Feb 20 '16 at 12:58