我有以下JSON:
{
"type": "champion",
"version": "6.24.1",
"data": {
"Jax": {
"id": 24,
"key": "Jax",
"name": "Jax",
"title": "Grandmaster at Arms",
"image": {
"full": "Jax.png",
"sprite": "champion1.png",
"group": "champion",
"x": 48,
"y": 48,
"w": 48,
"h": 48
}
},
"Sona": {
"id": 37,
"key": "Sona",
"name": "Sona",
"title": "Maven of the Strings",
"image": {
"full": "Sona.png",
"sprite": "champion3.png",
"group": "champion",
"x": 288,
"y": 0,
"w": 48,
"h": 48
}
}
}
}
RiotRequestManager收集字符串。我希望能够从LeagueObjectManager类中访问“full”和“sprite”的图像字符串。我得到了一个名单列表并提供了方法,我希望能够使用LeagueObject中的名称来提取图像。我在列表中单击他们的名称并尝试返回图像完整字符串。我尝试的所有内容都提供了空响应。
我有以下课程:
Imports Newtonsoft.Json
Public Class LeagueObjectManager
Private rrm As New RiotRequestManager
Private lc As LeagueObjectContainer
Private count As Integer
Public Sub New(ByVal strRegion As String, ByVal strMode As String)
lc = JsonConvert.DeserializeObject(Of LeagueObjectContainer)(rrm.returnLeagueItems(strRegion, strMode))
count = lc.data.Count()
End Sub
Public Function returnNames() As String()
Dim strReturn(count - 1) As String
Dim errorCount As Integer = 0
Dim counter As Integer = 0
For i = 0 To count - 1
If Not (lc.data.ElementAt(i).Value.name = "error") Then
strReturn(counter) = lc.data.ElementAt(i).Value.name
counter += 1
Else
errorCount += 1
ReDim Preserve strReturn(count - 1 - errorCount)
End If
Next
Return strReturn
End Function
End Class
Public Class LeagueObjectContainer
Public Property type As String
Public Property version As String
Public Property data As SortedDictionary(Of String, LeagueObject)
End Class
Public Class LeagueObject
Public Property id As Integer
Public Property key As String
Public Property name As String = "error"
Public Property title As String
Public Property image As SortedDictionary(Of String, LeagueImage)
Public Property group As String
Public Property tags As String()
Public Property enemytips As String
Public Property allytips As String
End Class
Public Class LeagueImage
Public Property full As String
Public Property sprite As String
End Class
答案 0 :(得分:3)
两个问题:
如果您的JSON结构已修复且无法更改,则可以通过在Visual Studio中选择Edit/Paste Special/Paste JSON as Classes
来获取关联的类层次结构。
答案 1 :(得分:3)
您可以使用多种效率来应对所拥有的内容。主要是,您不需要另一个类充当管理器:您要添加的任何方法或其他属性都可以添加到现有类中。使用稍微更惯用的名称:
Public Class DataItem
Public Property id As Integer
Public Property key As String
Public Property name As String = ""
Public Property title As String
Public Property image As ImageInfo
Public Overrides Function ToString() As String
Return name
End Function
End Class
Public Class ImageInfo
Public Property full As String
Public Property sprite As String
Public Property group As String
Public Property x As Integer
Public Property y As Integer
Public Property w As Integer
Public Property h As Integer
End Class
即使您对它们不感兴趣,我也会将所有图像属性保留在那里。然后容器类可以是容器和管理器类的混合:
Public Class LeagueManager
Public Property type As String
Public Property version As String
Public Property data As Dictionary(Of String, DataItem)
Public Sub New()
End Sub
' could/should be As IEnumerable(Of String)
Public Function GetPlayerNames() As String()
' enumerate Values collection of dictionary,
' filter out those with no name
' select/pick/use the DataItem.name
' put them in alpha order
' convert from IEnumerable to an array
Dim names = data.Values.AsEnumerable().
Where(Function(j) String.IsNullOrEmpty(j.name) = False).
Select(Function(q) q.name).
OrderBy(Function(k) k).
ToArray()
Return names
End Function
Public Function GetPlayer(name As String) As DataItem
' first first DataItem where the names match
Return data.Values.
FirstOrDefault(Function(q) String.Compare(name, q.name, StringComparison.InvariantCultureIgnoreCase) = 0)
End Function
Public Function GetPlayers() As DataItem()
Return data.Values.AsEnumerable().Cast(Of DataItem).ToArray()
End Function
End Class
allytips
。我猜你试图用1个以上的json?如果是这样,我可能不会合并经理和容器。Dictionary
而不是SortedDictionary
。以任何形式或顺序从Dictionary
获得您想要的任何内容都很容易。ToString()
上的DataItem
覆盖在调试时非常有用。如果你将管理器和容器结合起来,不要从构造函数中反序列化,我认为当JSON.NET创建另一个用于反序列化的循环时,你会进入无限循环。显式Load方法允许您(重新)加载其他参数/区域等的数据。
GetPlayer(string)
方法返回单个DataItem
,其中名称匹配(不区分大小写)。这不依赖于Dictionary
密钥,而是隐藏了实现的DataItems
中的实际名称,但如果可以删除/删除项目,则可以返回Nothing
:
Dim JaxData = myData.GetPlayer("jax")
If JaxData IsNot Nothing Then
...
End If
这将提供另一种使用从GetPlayerNames()
返回的名称来迭代集合的方法。您可以添加Count
,HasPlayer
以及您需要的任何其他属性和方法。至于图像,它只是DataItem上的另一个属性:
Dim jstr = ...
Dim leagueData = JsonConvert.DeserializeObject(Of LeagueManager)(jstr)
' get array of names
Dim names = leagueData.GetPlayerNames()
Dim di As DataItem
For Each s As String In names
' get DataItem object for player named in 's'
di = leagueData.GetPlayer(s)
If di IsNot Nothing Then
Console.WriteLine("{0} aka '{1}' uses image: '{2}'", di.name,
di.title, di.image.sprite)
Else
' very unlikely:
Console.WriteLine("Cannot find {0}", s)
End If
Next
结果:
贾克斯
索娜
Jax aka' Grandmaster at Arms'使用image:' champion1.png'
Sona aka' Maven of the Strings'使用image:' champion3.png'