从 DataGridView 创建 Json 属性

Creating Json Properties from DataGridView

提问人:tnils25 提问时间:10/10/2023 最后编辑:Ken Whitetnils25 更新时间:10/16/2023 访问量:60

问:

我不确定如何解释这一点,但这里是:

我正在尝试从 DataGridView 为 JSON 文件创建属性。我正在使用 newtonsoft 来处理 JSON 序列化。

从本质上讲,用户将他们的值添加到两列中,这些值将转换为属性。假设用户在 Column1 中输入值 10、20、30,然后在 Column2 中输入 “A” “B” “C”,则生成的 JSON 应为:

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

它应该根据用户创建的行数继续进行。

我以为我会分享我的代码,但是我不确定它是否有帮助,因为我什至不确定如何处理这个问题。

这些值将作为嵌套放在prompt_map字符串中

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

顺便说一下,这是我用来从 DataGridView 中提取数据的方法:

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

同样,不确定这有多大用处,只是展示了我的尝试。

任何帮助将不胜感激。我一天中的大部分时间都在做这件事。

JSON vb.net

评论


答:

1赞 Joel Coehoorn 10/10/2023 #1

一种选择是通过循环将行处理成 ,然后使用 Newtonsoft 序列化字典。Dictionary(Of String, String)

但是对于这么多工作,您可能还不如记住 JSON 只是一个字符串,去掉中间件,直接通过 StringBuilder 或类似工具构建结果。此外,Dictionary 方法不允许重复的键,虽然这可疑合法,但用户输入的数据可能是可能的。

' 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

评论

0赞 tnils25 10/10/2023
谢谢乔尔!当我调用此函数时:MsgBox(CreateJSON(DataGridView1))以检查其内容时,出现此错误:System.NullReferenceException:对象引用未设置为对象的实例。
0赞 Joel Coehoorn 10/10/2023
@user2359735 仅当 datagridview 中的 column2 少于两个时,才会发生这种情况。
0赞 tnils25 10/11/2023
仔细检查,我的 DataGridView1 中有两列(Column1 和 Column2)你是说它们都应该命名为 Column2 吗?
0赞 Joel Coehoorn 10/11/2023
不,此代码不关心列的名称。但是,这有可能被称为网格初始化之前或清除网格之后的点?
0赞 Joel Coehoorn 10/11/2023
嗯。。。我认为如果单元格的属性是 /,这也可能是可能的。有一个更新可以解决这个问题。ValuenullNothing
0赞 SSS 10/10/2023 #2

您可以使用 a 作为 ,并使用 a 来保存要序列化的数据。DataTableDataGridView.DataSourceDictionary(Of String, String)

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

输出:

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

评论

0赞 SSS 10/10/2023
归功于该部分的以下答案:stackoverflow.com/a/26874112/741136JObject
0赞 tnils25 10/11/2023
嘿 SSS,这实际上效果很好,这是我的输出:[{“10”:“A”},{“20”:“B”},{“30”:“C”}] 但是,有没有办法让它看起来更像我在原始问题中放置的示例?没有括号,把它嵌套到prompt_map,我不需要所有的括号,只需要在开头和结尾。希望是多行。我本质上想做的是将其添加到较长的序列化 Json 的中间。谢谢!
0赞 SSS 10/16/2023
我已经更新了我的答案。而不是 ,使用 和 包装类来添加节点JObjectDictionaryprompt_map