0

I'm not sure how to explain this, but here it goes:

I am trying to create properties for a JSON file from a DataGridView. I'm using newtonsoft to handle the JSON serializing.

Essentially, the user will add their values to two columns and those values will be turned into properties. Let's say the user puts in values 10, 20, 30 in Column1, and then in Column2 they put in "A" "B" "C", the resulting JSON should then be:

prompt_map: {
"10": "A"
"20": "B"
"30": "C"
}

And it should keep going depending on how many rows the user creates.

I thought I would share my code, however I'm not sure if it would help because I'm not even sure how to approach this.

The values will go in the prompt_map string as a nest

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      
    Dim myJson As JsonStructure
    myJson = New JsonStructure
    myJson.prompt_map

    Dim myString As String
    myString = JsonConvert.SerializeObject(myJson, Formatting.Indented)
    MsgBox(myString) 'debugging

End Sub

Public Class JsonStructure
    Public prompt_map As Frames
End Class

Public Class Frames
    'CODE GOES HERE?
End Class

This is the method I'm using to pull the data from the DataGridView by the way:

Dim colFrames As String
For i = 0 To DataGridView1.RowCount - 1
    If Not (DataGridView1.Rows(i).Cells("Column1").Value = 0) Then
        colFrames = colFrames + vbNewLine + (DataGridView1.Rows(i).Cells("Column1").Value)
    End If
Next

Dim colDesc As String
For i = 0 To DataGridView1.RowCount - 1
    If Not (DataGridView1.Rows(i).Cells("Column2").Value = 0) Then
        colDesc = colDesc + vbNewLine + (DataGridView1.Rows(i).Cells("Column2").Value)
    End If
Next

Again, not sure how useful this is, just showing my attempt.

Any help would be greatly appreciated. I've been going at this for most of the day.

2 Answers 2

1

One option is to process the rows via a loop into a Dictionary(Of String, String), and then use Newtonsoft to serialize the dictionary.

But for that much work, you might be as well off remembering that JSON is just a string, cutting out the middleware, and building the result directly via StringBuilder or similar. Additionally, the Dictionary method wouldn't allow for duplicate keys, which, while dubiously-legal, could be possible with user-entered data.

' Expect a datagridview with exactly two columns
Public Function CreateJSON(source As DataGridView) As String
    If source Is Nothing Then Return "prompt_map: {}"
    Dim result As New StringBuilder("prompt_map: {" & vbCrLf)

    Dim delimiter As String = ""
    For i As Integer = 0 To source.RowCount - 1
        result.Append($"{delimiter}""{FormatCell(source.Rows(i).Cells(0))}"":""{FormatCell(source.Rows(i).Cells(1))}""")
        delimter = $",{vbCrLf}"
    Next
    result.Append($"{vbCrLf}}")
    return result.ToString()
End Function

Private Function FormatCell(cell As DataGridViewCell) As String
    If cell Is Nothing OrElse cell.Value Is Nothing Then Return ""
    Return cell.Value.ToString().Replace("""", "\""")
End Function
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks Joel! When I call this function: MsgBox(CreateJSON(DataGridView1)) to check its contents I get this error: System.NullReferenceException: Object reference not set to an instance of an object.
@user2359735 That should only happen if there are less than two column2 in the datagridview.
Double checked, I have two columns in my DataGridView1 (Column1 and Column2) Are you saying they should both be named Column2?
No, this code doesn't care what the column is named. But it's possible this is called a point before the grid is initialized, or after it's cleared?
Hmm... I think this might also be possible if a cell's Value property is null/Nothing. There's an update to address this.
|
0

You can use a DataTable as your DataGridView.DataSource, and use a Dictionary(Of String, String) to hold the data for serialization.

Imports Newtonsoft.Json.Linq

Public Class Form1
  'Add a DataGridView and a Button to the form

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    Dim gridData = New DataTable("SettingsData")
    gridData.Columns.Add(New DataColumn("Column1", GetType(String)))
    gridData.Columns.Add(New DataColumn("Column2", GetType(String)))
    DataGridView1.DataSource = gridData
  End Sub

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim gridData = DirectCast(DataGridView1.DataSource, DataTable)
    Dim output = New OutputClass
    For rowIndex As Integer = 0 To gridData.Rows.Count - 1
      Dim row = gridData.Rows(rowIndex)
      Dim col1Value = row(0).ToString
      Dim col2Value = row(1).ToString
      output.prompt_map.Add(col1Value, col2Value)
    Next rowIndex
    Dim outputJson = Newtonsoft.Json.JsonConvert.SerializeObject(output)
    System.IO.File.WriteAllText("C:\Junk\junk.json", outputJson)
  End Sub

  Class OutputClass
    Public Property prompt_map As New Dictionary(Of String, String)
  End Class
End Class

Output:

{
  "prompt_map": {
    "10": "A",
    "20": "B",
    "30": "C"
  }
}

3 Comments

Credit to the following answer for the JObject part: stackoverflow.com/a/26874112/741136
Hey SSS, this actually works pretty well, here is my output: [{"10":"A"},{"20":"B"},{"30":"C"}] However, is there anyway to make it look more like the example I put in my original question? No brackets, and nest it into prompt_map, I don't need all the brackets, just at the beginning and end. And hopefully multiline. What I'm essentially trying to do is add this into the middle of a longer serialized Json. Thank you!
I've updated my answer. Instead of JObject, use a Dictionary and a wrapper class to add the prompt_map node

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.