JSON至具有可变根的DataTable网络

时间:2018-11-23 19:30:56

标签: json vb.net

这是我第一次与JSON打交道,很遗憾,我必须在VB.Net公司政策中这样做。因此,我四处搜寻,并尝试了许多示例,甚至将某些C#代码转换为VB.Net,但似乎找不到完整的解决方案。

我收到这样的JSON字符串:

{
   "65080007":{
      "partNo":"ATD000007",
      "description":"Swingarm Hat Platform",
      "quantity":4,
      "assemblyseq":""
   },
   "65080143":{
      "partNo":"ATD000143",
      "description":"ASY Gas Spring Bracket",
      "quantity":2,
      "assemblyseq":""
   },
   "65080071":{
      "partNo":"ATD000071",
      "description":"TT Gas Spring",
      "quantity":2,
      "assemblyseq":""
   },
   "65080147":{
      "partNo":"ATD000147",
      "description":"ASY Lateral Hinge",
      "quantity":8,
      "assemblyseq":""
   },
   "65085181":{
      "partNo":"RD0181",
      "description":"ASY KIT Bolt, Carriage, 0.375 in x 16, 1.5 in (x45) & Nut, Flange, 0.375 in x 16 (x45)",
      "quantity":1,
      "assemblyseq":""
   },
   "65080796":{
      "partNo":"ATD000796",
      "description":"Decal, TT Equipped, Rectangular, 5 in x 10 in",
      "quantity":1,
      "assemblyseq":""
   },
   "65080797":{
      "partNo":"ATD000797",
      "description":"Decal, TT Open/Close, Triangular, 12 in x 8 in",
      "quantity":1,
      "assemblyseq":""
   },
   "65080745":{
      "partNo":"ATD000745",
      "description":"",
      "quantity":1,
      "assemblyseq":""
   }
}

我需要做的是将此数据绑定或分配给DataGridView.DataSource
我已经看到了一些示例,但无法将其设置为DataSource
我已经尝试过以下示例:

Sub Main()
    Dim json_result = GetJson()
    Dim table = JsonConvert.DeserializeAnonymousType(json_result, (DataTable))
    Dim newJString = Newtonsoft.Json.JsonConvert.SerializeObject(table, Newtonsoft.Json.Formatting.Indented)

    Console.WriteLine("Re-serialized JSON: ")
    Console.WriteLine(newJString)
    Console.WriteLine("")
End Sub

Public Function GetJson() As String
    Dim json_result As String = <![CDATA[
    ' I used the above json string
    Return json_result
End Function

我制作了JSON类以对JSON进行反序列化,并尝试JsonConvert.Deserialize不断出现错误,它选择了一个数组并找到了一个对象。

Public Class Jobs
    '<JsonProperty("partno")>
    Public Property PartNo As String
    ' <JsonProperty("description")>
    Public Property Description As String
    '<JsonProperty("quantity")>
    Public Property Quantity As String
    '<JsonProperty("assemblyseq")>
    Public Property Assemblyseq As String
End Class

我认为问题是根属性"65080797"每次我们从JSON返回NetSuite时,这些数字都不相同。

所以我尝试:

Dim obj = JsonConvert.DeserializeObject(Of Jobs)(result)
Console.WriteLine(obj.PartNo) it comes out PartNo = nothing

所以我尝试了这个:

Dim resultA = JsonUtil.Deserialize(Of Jobs)(result, ignoreRoot:=True)
Module JsonUtil
    Function Deserialize(Of T As Class)(ByVal json As String, ByVal ignoreRoot As Boolean) As T
    Return If(ignoreRoot, JObject.Parse(json)?.Properties()?.First()?.Value?.ToObject(Of T)(), JObject.Parse(json)?.ToObject(Of T)())
    End Function
End Module

这给了我第一组:

ATD000007
Swingarm Hat Platform
4

程序集号为空。
对于有关如何将上述JSON放入数据表或DataGridView或如何在没有根"65080797"的情况下创建列表的任何建议,我都愿意接受。对于每个响应,此数字都是唯一的。
设计此响应字符串的人员拒绝删除根属性。

感谢您抽出宝贵的时间阅读这份烂摊子。
感谢所有评论/建议。

2 个答案:

答案 0 :(得分:0)

如果您具有类似的异常结构化JSON,最好的选择可能是使用原始JObject和JToken处理,而不是尝试使JSON.NET自动反序列化为结构化数据。

创建一个将单个JToken转换为您在问题中描述的Job类的方法。我添加了一个Key属性,以识别JSON中对您有问题的唯一键;如果不需要这些,只需从下面的示例中删除.Key位。

Public Function CreateJob(data As JToken)
    Return New Job With
    {
        .Key = data.Path,
        .PartNo = data("partNo"),
        .Description = data("description"),
        .Quantity = data("quantity"),
        .Assemblyseq = data("assemblyseq")
    }
End Function

一旦创建了Job对象,就可以遍历整个结构并将其转换为具有以下示例代码的作业数组。

Dim result As JObject = JsonConvert.DeserializeObject(json)
Dim jobs As Job() = result.Values().Select(Of Job)(AddressOf CreateJob).ToArray()

一旦您有一个Job对象数组,绑定到DataSource应该很简单。

答案 1 :(得分:0)

是的,Json数组看起来像[something]而不是{somthing},您可以根据需要将其转换为array,但也可以采用其他方式进行操作,即使没有任何外部库,也可以创建数据表然后进行绑定它将其添加到datagridview,或者您可以将数据直接添加到datagridview。

无论如何,我为您制作了一个数据表。

    Imports System.Web.Script.Serialization 'for reading of JSON (+add the reference to System.Web.Extensions library)
    Dim JSONC = New JavaScriptSerializer().Deserialize(Of Dictionary(Of String, Dictionary(Of String, String)))(JSON) 'you could do it in different ways too
    Dim NewDT As New DataTable
    'Create Columns
    For Each key In JSONC.First.Value.Keys 
    '"65080007" <first
    '{ "partNo":"ATD000007", "description":"Swingarm Hat Platform", "quantity":4, "assemblyseq":"" } <first.value
    ' "partNo" <first.value.key(s) :"ATD000007" <first.value.value(s) 
        NewDT.Columns.Add(key)
    Next
    'Add Rows
    For Each item In JSONC
        NewDT.Rows.Add(item.Value.Values.ToArray)
    Next
    DataGridView1.DataSource = NewDT

enter image description here