反序列化JSON字符串,该字符串是数组并具有非法的属性名称

时间:2016-05-23 21:23:04

标签: json vb.net json.net json-deserialization

我使用JSON.NET从HTTP查询反序列化JSON响应,但我在反序列化方面遇到了问题。

源JSON就是这样:

[
  {
    "type": "rpc",
    "tid": 18,
    "action": "TaskSystem",
    "method": "createTask",
    "result": {
      "0": {
        "success": true,
        "successes": [
          [
            "Task successfuly created with S/N #22920"
          ]
        ]
      },
      "1": {
        "success": true,
        "successes": [
          [
            "Task successfuly created with S/N #22921"
          ],
          "Task #22921 marked as urgent"
        ]
      },
      "records": [
        {
          "id": 22920
        },
        {
          "id": 22921
        }
      ],
      "success": true
    }
  }
]

我一直在使用这些类进行反序列化:

Private Sub Deserialize()
    Dim Jobj = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Response())(Jstring)
End Sub

Public Class Record
    Public Property id As Integer
End Class

Public Class Result
    Public Property records As Record()
    Public Property success As Boolean
End Class

Public Class Response
    Public Property type As String
    Public Property tid As Integer
    Public Property action As String
    Public Property method As String
    Public Property result As Result
End Class

但后来我丢失了查询返回的成功/失败消息

如何编写课程结果以便收集属性记录为记录()成功为布尔那些名为" 0"," 1"等等......?

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以将JSON复制到剪贴板并使用
    修改 - >选择性粘贴 - >将JSon粘贴为类
从课堂上得到粗略的。所有机器人都会错误地将其中的部分内容弄错,例如:

' wrong
Public Property successes()() As String
' correct:
Public Property successes As String()()

这似乎有效:

Public Class StatusS          ' string()() version
    Public Property success As Boolean
    Public Property successes As List(Of List(Of String))
End Class

Public Class StatusO         ' Object() version
    Public Property success As Boolean
    Public Property successes As List(Of Object)
End Class

机器人也非常难以使用非法的属性名称,特别是在VB中有很多关键字(EndError很常见)。使用JsonProperty创建别名(将“0”或“1”映射到合法的地方):

Public Class Result
    <JsonProperty("0")>
    Public Property StatusA As StatusS
    <JsonProperty("1")>
    Public Property StatusB As StatusO
    Public Property records As List(Of Record)
    Public Property success As Boolean
End Class

他们提供数组的任何地方,您都可以改为使用List(Of T)

Dim jData = JsonConvert.DeserializeObject(Of Response())(jstr)

Console.WriteLine(jData(0).action)
Console.WriteLine(jData(0).result.records(0).id)
Console.WriteLine(jData(0).result.StatusA.success)
Console.WriteLine(jData(0).result.StatusA.successes(0)(0).ToString)
Console.WriteLine(jData(0).result.StatusB.successes(0).ToString)

结果:

  

TaskSystem
  22920个
  真
  任务使用S / N#22920成功创建   [
    “使用S / N#22921成功完成任务”
  ]

很难发现[ "Task successfuly ... #22920" ]之后的遗失/额外逗号导致Object版本与String()()之间的一个或另一个可能是拼写错误。如果没有,你可以为这两个编写一个转换器,或者为{+ 1}}类添加一个方法来获取Q + D意味着删除括号:

StatusO
  

使用S / N#22921

成功创建任务

答案 1 :(得分:1)

这里有两个无关的问题:

  1. 您的class Brain_images extends CI_Model { function get_image() { $sql = "select image from brain where id = (select MAX(id) from brain)"; $query = $this->db->query($sql); return $query->row()->image; } } 类由一组固定属性和一组变量属性组成,这些属性具有递增的数字名称和值的标准化架构。您希望自动反序列化标准属性,并捕获和反序列化自定义属性。

    可以使用JsonExtensionData完成此操作。使用此属性,您可以暂时将自定义属性反序列化为Result,然后在[OnDeserialized]回调中转换为Dictionary(of String, JToken)。这里Dictionary(Of String, Success)是一个设计用于捕获JSON的类型:

    Success

    有关文档,请参阅Deserialize ExtensionData

  2. 在上述{ "success": true, "successes": [ [ "Task successfuly created with S/N #22920" ] ] } 类型中,Success数组包含字符串数组和单个字符串。

    如果您按如下方式定义"successes"属性:

    successes

    然后,可以使用How to handle both a single item and an array for the same property using JSON.netPublic Property successes As List(Of List(Of String)) 的变体来处理此问题,并通过SingleOrArrayConverter(Of String)将其设置为item converter

  3. 因此,您的最终课程将如下所示:

    <JsonProperty(ItemConverterType := GetType(SingleOrArrayConverter(Of String)))>

    原型fiddle