我正在尝试将以下JSON示例转换为vb.net类,或者只是简单地读取信息。我可以得到第一部分ID
,name
和objCode
,但是我不能解析parameterValues
,因为列名中有空格。因此,我无法将类字段名称分配为[DE:App code]
。这来自自定义模板,因此字段名称可以称为任何名称。我需要遍历所有parameterValues
并获取名称和值,以便可以将它们添加到数据库中。我需要的主要值(永远存在)是ID
,DE:App Code
和DE:App Alloc 1 Code
。
{
"data": [
{
"ID": 43545325253,
"name": "FY1955: PAT",
"objCode": "PROJ",
"parameterValues": {
"DE:": "PS12",
"DE:Please Enter Requested": "/rss55.edu",
"DE:URL Allocation 1": "Society Scholarship",
"DE:Is this being created for other purposes?": "no",
"DE:Request Submitted by": "urser55",
"DE:Project Owner": "Admin User",
"DE:App Code": "YDAR",
"DE:App Completion Date": "2018-12-14",
"DE:App Alloc 1 Code": "SBDRC"
}
}
]
}
有人对我如何解决这个问题有任何想法吗?如果您可以提供任何VB.Net示例代码,那就太好了。
似乎要求已经改变。他们在参数中添加了另一个子片段,这使我的代码在“ DE:App Units”上崩溃了。这是JSON现在的样子:
{
"data": [
{
"ID": 43545325253,
"name": "FY1955: PAT",
"objCode": "PROJ",
"parameterValues": {
"DE:": "PS12",
"DE:Please Enter Requested": "/rss55.edu",
"DE:URL Allocation 1": "Society Scholarship",
"DE:Is this being created for other purposes?": "no",
"DE:Request Submitted by": "urser55",
"DE:Project Owner": "Admin User",
"DE:App Code": "YDAR",
"DE:App Completion Date": "2018-12-14",
"DE:App Units": [
"University-Wide",
"All Colleges"
],
"DE:App 1 Long Name - 1": "Pref Univ",
"DE:Mailing Components": [
"Reply Envelope",
"Outer Envelope",
"Letter"
],
"DE:App Alloc 1 Code": "ABBRC"
}
}
]
}
如何使它与新JSON一起使用?
答案 0 :(得分:1)
由于您的参数名称可以是任何名称,因此建议您在该部分使用Dictionary(Of String, String)
。像这样声明模型类:
Class RootObject
Public Property Data As List(Of Item)
End Class
Class Item
Public Property ID As String
Public Property Name As String
Public Property ObjCode As String
Public Property ParameterValues As Dictionary(Of String, String)
End Class
使用像Json.Net这样的不错的JSON库,您可以轻松地将JSON反序列化为以下模型:
Dim root As RootObject = JsonConvert.DeserializeObject(Of RootObject)(json)
从那里您可以像使用其他任何类一样使用模型。例如,以下是将所有数据转储到控制台的方法:
For Each item In root.Data
Console.WriteLine("ID: " & item.ID)
Console.WriteLine("Name: " & item.Name)
Console.WriteLine("ObjCode: " & item.ObjCode)
Console.WriteLine()
Console.WriteLine(String.Format("{0,-45} {1}", "Parameter Name", "Parameter Value"))
Console.WriteLine(New String("-", 45) & " " & New String("-", 20))
For Each kvp In item.ParameterValues
Console.WriteLine(String.Format("{0,-45} {1}", kvp.Key, kvp.Value))
Next
Next
正在运行的演示:https://dotnetfiddle.net/SqInI6
要处理您的更新:
看起来您的每个参数值现在都可以是单个字符串或字符串数组。这将导致当前代码崩溃,因为字典只能包含简单的字符串值。您可以将字典声明更改为Dictionary(Of String, Object)
,这将使其反序列化,但是如果这样做,您最终将在字典中混合使用字符串和JArrays
。然后,您将需要在所有使用它的地方检查值的类型并适当地处理它,例如:
If kvp.Value Is GetType(JArray) Then
Dim list As List(Of String) = DirectCast(kvp.Value, JArray).ToObject(Of List(Of String))
... handle multiple values ...
Else
Dim str As String = DirectCast(kvp.Value, String)
... handle single value ...
End If
我认为更好的解决方案是将字典更改为Dictionary(Of String, List(Of String))
,然后使用自定义JsonConverter
从JSON填充字典。这样您就可以在其余的代码中统一处理这些值,因为您知道您将始终拥有一个字符串列表。
如果采用这种方法,则需要以下转换器:
Public Class SingleOrArrayDictionaryConverter(Of T)
Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return objectType = GetType(Dictionary(Of String, List(Of T)))
End Function
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim obj = JObject.Load(reader)
Dim dict = New Dictionary(Of String, List(Of T))
For Each prop In obj.Properties()
If prop.Value.Type = JTokenType.Array Then
dict.Add(prop.Name, prop.Value.ToObject(Of List(Of T)))
Else
dict.Add(prop.Name, New List(Of T) From {prop.Value.ToObject(Of T)})
End If
Next
Return dict
End Function
Public Overrides ReadOnly Property CanWrite As Boolean
Get
Return False
End Get
End Property
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
Throw New NotImplementedException()
End Sub
End Class
要使用转换器,请将<JsonConverter>
属性添加到ParameterValues
属性中,如下所示:
<JsonConverter(GetType(SingleOrArrayDictionaryConverter(Of String)))>
Public Property ParameterValues As Dictionary(Of String, List(Of String))