我对使用 JSON.net 还很陌生,并且在使用一些 json 时遇到了问题,有时作为数组出现,有时作为单个对象出现。这是我在 json 中看到的示例
它进来的一种方式......
{
"Make": "Dodge",
"Model": "Charger",
"Lines": [
{
"line": "base",
"engine": "v6",
"color": "red"
},
{
"line": "R/T",
"engine": "v8",
"color": "black"
}
],
"Year": "2013"
}
它可以进入的另一种方式
{
"Make": "Dodge",
"Model": "Charger",
"Lines": {
"line": "base",
"engine": "v6",
"color": "red"
},
"Year": "2013"
}
这是我一直在使用的代码,它以第一种方式工作并在第二种情况下引发异常。一直在网上搜索实现这一点的方法,我真的被困住了。
Public Class jsonCar
Public Property make As String
Public Property model As String
Public Property lines As List(Of jsonCarLines)
Public Property year As String
End Class
Public Class jsonCarLines
Public Property line As String
Public Property engine As String
Public Property color As String
End Class
Module Module1
Private Const json As String = "{""Make"":""Dodge"",""Model"":""Charger"",""Lines"": [{""line"":""base"",""engine"": ""v6"",""color"":""red""},{""line"":""R/T"",""engine"":""v8"",""color"":""black""}],""Year"":""2013""}"
'Private Const json As String = "{""Make"":""Dodge"",""Model"":""Charger"",""Lines"": {""line"":""R/T"",""engine"":""v8"",""color"":""black""},""Year"":""2013""}"
Sub Main()
Dim car As jsonCar = JsonConvert.DeserializeObject(Of jsonCar)(json)
Console.WriteLine("Make: " & car.make)
Console.WriteLine("Model: " & car.model)
Console.WriteLine("Year: " & car.year)
Console.WriteLine("Lines: ")
For Each ln As jsonCarLines In car.lines
Console.WriteLine(" Name: " & ln.line)
Console.WriteLine(" Engine: " & ln.engine)
Console.WriteLine(" Color: " & ln.color)
Console.WriteLine()
Next
Console.ReadLine()
End Sub
End Module
我猜这可能需要一个自定义的 JsonConverter,但我对如何设置它有点不知所措。
最佳答案
以下是获取 SingleOrArrayConverter
的方法链接中的解决方案duplicate question为您的用例工作。
首先,这里是VB翻译的转换器代码。将其保存到项目中某处的类文件中。然后,您可以轻松地将其重用于任何类似的 future 案例。
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class SingleOrArrayConverter(Of T)
Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return objectType = GetType(List(Of T))
End Function
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim token As JToken = JToken.Load(reader)
If (token.Type = JTokenType.Array) Then
Return token.ToObject(Of List(Of T))()
End If
Return New List(Of T) From {token.ToObject(Of T)()}
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
注释该列表。属性使其使用 SingleOrArrayConverter
类(class)。在你的情况下,这看起来像这样:Public Class jsonCar
Public Property make As String
Public Property model As String
<JsonConverter(GetType(SingleOrArrayConverter(Of jsonCarLines)))>
Public Property lines As List(Of jsonCarLines)
Public Property year As String
End Class
然后,像往常一样反序列化,它会按预期工作。
Dim car As jsonCar = JsonConvert.DeserializeObject(Of jsonCar)(json)
这是一个完整的演示:https://dotnetfiddle.net/msYNeQ
关于json - 如何反序列化可以是数组或单个对象的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28395700/