我的應用程序處理很多返回JSON數據的HTTP請求。我使用JSON.NET庫來處理它。JSON.NET對象的數據綁定:如何實現?
我需要這些數據顯示在Winforms數據綁定控件(主要是ComboBox
和DataGridView
)。目前沒有數據編輯的意圖,只需要以用戶友好的方式顯示數據。
我寫的轉換IEnumerable(Of JToken)
一個簡易的轉換例程到DataTable
:
Module JsonAsDataTable
<Runtime.CompilerServices.Extension> Public Function ToDataTable(ByVal jtokens As IEnumerable(Of JToken), Optional ByVal trim_object_columns As Boolean = False, Optional ByVal castToCLRtypes As Boolean = False, Optional ByVal orderBy As String = Nothing) As DataTable
Dim dt As New DataTable, sdt As DataTable, dr, sdr As DataRow, dateproperty As Date
If jtokens IsNot Nothing Then
For Each jt In jtokens
dr = dt.NewRow
For Each jp In jt.Children(Of JProperty)
sdt = Nothing
If Not dt.Columns.Contains(jp.Name) Then dt.Columns.Add(jp.Name, IIf(castToCLRtypes, GetType(Object), GetType(JToken)))
If jp.Value.Type = JTokenType.Object AndAlso jp.Value.Children.Count = 1 AndAlso jp.Value.First.Type = JTokenType.Property AndAlso DirectCast(jp.Value.First, JProperty).Name = "date" Then
If Date.TryParse(DirectCast(jp.Value.First, JProperty).Value, dateproperty) Then
dr.SetField(jp.Name, New JValue(dateproperty))
Else
dr.SetField(jp.Name, JValue.CreateNull)
End If
Else
dr.SetField(jp.Name, jp.Value)
If jp.Value.Type = JTokenType.Object Then
sdt = AsDataTable({jp.Value}, trim_object_columns)
ElseIf jp.Value.Type = JTokenType.Array Then
sdt = AsDataTable(jp.Value, trim_object_columns)
End If
If sdt IsNot Nothing Then
sdr = sdt.Select.FirstOrDefault
For Each sdc As DataColumn In sdt.Columns
If Not dt.Columns.Contains(jp.Name & "." & sdc.ColumnName) Then dt.Columns.Add(jp.Name & "." & sdc.ColumnName, GetType(Object))
If sdr IsNot Nothing Then dr.SetField(jp.Name & "." & sdc.ColumnName, sdr(sdc.ColumnName))
Next
If trim_object_columns Then dt.Columns.Remove(jp.Name)
End If
End If
Next
dt.Rows.Add(dr)
Next
If castToCLRtypes Then
For Each drow In dt.Select
For Each dcol As DataColumn In dt.Columns
If TypeOf drow(dcol) Is JToken Then drow(dcol) = ToField(drow(dcol))
Next
Next
End If
If dt.Rows.Count > 0 AndAlso Not String.IsNullOrEmpty(orderBy) Then
dt = dt.Select("", orderBy).CopyToDataTable
End If
End If
Return dt
End Function
<Runtime.CompilerServices.Extension> Friend Function ToField(token As JToken) As Object
If token Is Nothing Then Return Nothing
Select Case token.Type
Case JTokenType.Boolean
Return token.Value(Of Boolean)
Case JTokenType.Bytes
Return token.Value(Of Byte())
Case JTokenType.Date
Return token.Value(Of Date)
Case JTokenType.Float
Return token.Value(Of Double)
Case JTokenType.Guid
Return token.Value(Of Guid)
Case JTokenType.Integer
Return token.Value(Of Integer)
Case JTokenType.Null
Return Nothing
Case JTokenType.Property
Return ExtractObjectFrom(CType(token, JProperty).Value)
Case JTokenType.String
Return token.Value(Of String)
Case JTokenType.TimeSpan
Return token.Value(Of TimeSpan)
Case JTokenType.Uri
Return token.Value(Of Uri)
Case Else
Return token.ToString
End Select
End Function
End Module
現在我知道我的解決方案是既不乾淨,也不可靠。這只是我爲了讓事情在DataGridView
中顯示的第一件事情,用戶可以通過單擊列標題對數據進行排序,這種簡單的JToken Array不允許。
因此,我想編寫一個自定義類來包裝這些JToken對象,也許是一個Collection類,以DataGridView
易於理解和處理的方式列出它們,從而實現排序等功能(這對我來說很重要)和篩選(這將成爲Achiev3e的額外獎勵)。
我的問題是:這是最小的一組接口這些類應實現,以實現這一目標?