Introduction
Recently I found that the Json format is quite useful compared to very complex XML. I use the Json format to save some hierarchical data for which table-based database is hard to handle. I also needed some user interface to manipulate this nested structure Json text data. This could be useful if you deal with a very dynamic object like data structure which gives a lot of trouble to be saved directly to the table in database. This is beginner level in terms of ASP.NET skill.
Using the Code
JsonEditorTable
class is extended Table
class to dynamically create its table structure when parsing Json text. It creates a child table to display nested structure of the Json data.
Public Class JsonEditorTable : Inherits Table
Private _JObject As JObject
Private _BindingCollection As New Hashtable()
Public Property JsonContext() As String
Get
Me.JsonDataBind()
Return Me._JObject.ToString()
End Get
Set(ByVal value As String)
Me.Controls.Clear()
Me.GenerateTable(value)
Me.ViewState("JsonContext") = value
End Set
End Property
Private Sub GenerateTable(ByVal jsonContext As String)
Dim str As New System.IO.StringReader(jsonContext)
Dim jobj As JObject = JObject.Parse(str.ReadToEnd())
str.Close()
Me._JObject = jobj
str.Close()
For Each p As JProperty In jobj.Properties
RenderJProperty(Me, p)
Next
End Sub
#Region "Json Implementation"
Private Sub RenderJProperty(ByVal tb As Table, ByVal jp As JProperty)
If jp.Value.GetType() Is GetType(JValue) Then
tb.Rows.Add(Me.CreateJsonRow(jp))
Else
If jp.Value.Type = JsonTokenType.Array Then
Exit Sub
End If
Dim ctb As Table = CreaeteJsonTable(jp.Name)
Try
For Each p As JProperty In jp.Value.Children
RenderJProperty(ctb, p)
Next
Catch ex As Exception
Throw New Exception(ex.Message & "::" & jp.Name)
End Try
Dim c As New TableCell
c.ColumnSpan = 2
c.Style.Add("padding-left", "30px")
c.Controls.Add(ctb)
Dim r As New TableRow
r.Cells.Add(c)
tb.Rows.Add(r)
End If
End Sub
Private Function CreateJsonRow(ByVal jp As JProperty)
Dim r As TableRow
Dim c As TableCell
r = New TableRow()
c = New TableCell()
c.Font.Bold = True
c.Text = jp.Name
r.Cells.Add(c)
Dim box As WebControl
box = JsonEditorBoxFactory.CreateJsonBox(jp.Value, jp.Value.Type)
Me.Bind(jp, box)
c = New TableCell()
c.Font.Bold = True
c.Controls.Add(box)
r.Cells.Add(c)
Return r
End Function
Create a different type of TextBox
using polymorphism such as NumberBox
, StringBox
, BooleanBox
for editing.
Public Class NumberBox : Inherits TextBox
Implements IJsonEditorBox
Sub New(ByVal value As JValue)
Me.Value = value
End Sub
Property Value() As JValue Implements IJsonEditorBox.Value
Get
If Me.Text Is Nothing Then
Return Nothing
End If
Try
Return New JValue(Convert.ToInt32(Me.Text))
Catch ex As Exception
Return Nothing
End Try
End Get
Set(ByVal value As JValue)
If value.Type = JsonTokenType.Null Then
Me.Text = Nothing
Else
Me.Text = value.Value.ToString()
End If
End Set
End Property
End Class
Public Class StringBox : Inherits TextBox
Implements IJsonEditorBox
Sub New(ByVal value As JValue)
Me.Value = value
End Sub
Property Value() As JValue Implements IJsonEditorBox.Value
Get
If Me.Text = "" Then
Return Nothing
Else
Return New JValue(Me.Text)
End If
End Get
Set(ByVal value As JValue)
Me.Text = value.Value
End Set
End Property
End Class
Public Class BooleanBox : Inherits DropDownList
Implements IJsonEditorBox
Sub New(ByVal value As JValue)
Dim item As ListItem
item = New ListItem("null", "null")
Me.Items.Add(item)
item = New ListItem("false", "false")
Me.Items.Add(item)
item = New ListItem("true", "true")
Me.Items.Add(item)
Me.SelectedValue = value.ToString()
End Sub
Property Value() As JValue Implements IJsonEditorBox.Value
Get
Return GetValue()
End Get
Set(ByVal value As JValue)
Me.SelectedValue = value.ToString()
End Set
End Property
Function GetValue() As JValue
If Me.SelectedValue = "true" Then
Return New JValue(True)
ElseIf Me.SelectedValue = "false" Then
Return New JValue(False)
Else
Return Nothing
End If
End Function
End Class
Points of Interest
I actually use some schema files to create a more dynamic user interface of this Json text editor. Some property may be read only, or some property can display some useful tooltip and icon to help the user to make the correct change.
History
- 12th February, 2009: Initial post