设置嵌套JSON对象的属性
我是JSON.Net的新手,还没有弄清楚如何将JSON的嵌套对象作为设置嵌套JSON对象的属性,json,vb.net,winforms,json.net,Json,Vb.net,Winforms,Json.net,我是JSON.Net的新手,还没有弄清楚如何将JSON的嵌套对象作为JObject。我使用一个文件来存储JSON对象,然后将所做的更改写回该文件 背景 我正在尝试制作一个应用程序,用户在其计算机上选择一个文件夹,该应用程序将该文件夹及其所有文件枚举到一个JSON对象中。然后,用户可以选择这些文件中的任何一个,并设置要保存到JSON文件的文件的值。到目前为止,我已经实现了将目录结构/包含的文件生成为JSON并将其保存到文件中的功能,但我一直在尝试访问JSON的嵌套对象以设置属性值 到目前为止我的代
JObject
。我使用一个文件来存储JSON对象,然后将所做的更改写回该文件
背景
我正在尝试制作一个应用程序,用户在其计算机上选择一个文件夹,该应用程序将该文件夹及其所有文件枚举到一个JSON对象中。然后,用户可以选择这些文件中的任何一个,并设置要保存到JSON文件的文件的值。到目前为止,我已经实现了将目录结构/包含的文件生成为JSON并将其保存到文件中的功能,但我一直在尝试访问JSON的嵌套对象以设置属性值
到目前为止我的代码
用于生成JSON并将其存储到文件中的代码为:
Private Sub btnAddFolder_Click(sender As Object, e As EventArgs) Handles btnAddFolder.Click
'Create JObject from JSON File
Dim json = File.ReadAllText(jsonFile)
Dim obj As New JObject
If json <> "" Then
obj = JObject.Parse(json)
End If
'Add directory as a nested object of JSON
' - Add all of files in directory as nested objects of the directory object
If obj.Property(txtDirectory.Text) Is Nothing Then
'Object to store all files as nested objects
Dim files As New JObject
'Object to store all properties of a file object
Dim fileInfo As New JObject
'Variables to store properties for fileInfo
Dim stringProp As String = "default"
Dim arrProp() As String = {"default"}
Dim jArrProp As JArray = JArray.FromObject(arrProp)
'Add properties to objcet
fileInfo.Add("var1", stringProp)
fileInfo.Add("var2", jArrProp)
'Add object of properties to each file object
For Each file As String In Directory.GetFiles(txtDirectory.Text)
files.Add(file, fileInfo)
Next
'Add each file object to directory object
obj.Add(txtDirectory.Text, files)
End If
'Write JSON to file
File.WriteAllText(jsonFile, JsonConvert.SerializeObject(obj, 1))
End Sub
我接下来需要什么
单击标有“添加文件夹”的按钮时,会调用上面的代码。另一个按钮标记为
Select File and Set Data
,提示用户从目录中选择任何文件,并输入将存储在该文件的var1
和var2
中的值
例如,当点击选择文件和设置数据
按钮时,用户选择文件1
,然后在文本框中写入“此文件是我2012年到群岛度假的照片”。我需要我的代码将obj.Directory1.File1的var1
设置为指定的字符串值。
这就是我被难倒的地方。我不知道如何使用JSON.net访问嵌套对象以设置其属性之一的值
我知道一个JObject
有一个.Property().Value()
方法,可以用来设置或获取属性的值,但是由于我想要的JSON对象嵌套在主JSON对象中,我不知道如何将其作为JObject
来访问该方法JObject.Item()
返回一个JToken
,该JToken没有.Property().Value()
方法。您的JSON结构包含目录名或完整路径,它们都是不同的,因此类模型对于描述此JSON的全部内容并不是很有用。
由于目录路径是唯一的(不能有两个指向不同目录根的相同路径),因此可以将目录路径用作字典的键。
使用Dictionary.ContainsKey(“Key”)
方法确定字典是否已经包含该键也很简单(因为您正在代码中检查该键)
这同样适用于文件名:通常目录不能包含具有相同名称的文件。因此,您可以使用文件路径作为第二个字典的键,这是第一个字典的值(如上所述,它将目录作为键)
相反,var1
和var2
的值总是相同的,因此可以使用类模型来描述此结构。您还可以为属性指定默认值(以不同的方式;这里我只是显式地指定默认值)
将新目录结构添加到当前词典:
Private Sub btnAddFolder_Click(sender As Object, e As EventArgs) Handles btnAddFolder.Click
Dim dirPath = txtDirectory.Text
If DirectoryObjects.ContainsKey(dirPath) Then Return
Dim fileInfo As New Dictionary(Of String, FileObj)()
For Each file As String In Directory.GetFiles(dirPath)
fileInfo.Add(file, New FileObj() With {
.Var1 = "Something",
.Var2 = New List(Of String)({"Something", "Else"})
})
Next
DirectoryObjects.Add(dirPath, fileInfo)
' Now you can serialize and write to disc to preserve the changes
Dim dirInfoJson = JsonConvert.SerializeObject(DirectoryObjects)
File.WriteAllText(jsonFile, dirInfoJson)
End Sub
现在,您可以使用组合框(例如)来选择其中一个目录,使用列表框/列表视图来显示所选目录的内容。
选择一个文件时,目录是外部字典的键,文件是内部字典的键。
► Dictionary.ToList()
可以用作保存项集合的大多数控件的数据源
txtDescription.Text
表示与var1
txtDataVar2a.Text
和txtDataVar2b.Text
表示var2
值的其他输入
您将看到此JSON结构与此处显示的结构相同
注意:
新文件系统中的文件名可能区分大小写,但这不是问题,因为我们的字符串比较也区分大小写。这是一个完美的解决方案,Jimi,非常感谢您为此花费的时间和精力。对于其他任何发现这一点的人:我的问题的一般答案是:创建一个模仿JSON属性的类,然后制作一个嵌套的字典
,其嵌套量与您的JSON相同,而字典
中的最后一个条目则与您的类类型相同。然后,对Dict对象进行更改并将其序列化回JSON文件。值得注意的是,如果.json文件完全为空,代码将失败。您的“空白”文件应该是“{}”,因此代码将生成一个空对象,而不是无对象。
Public Class FileObj
<JsonProperty("var1")>
Public Property Var1 As String = "default"
<JsonProperty("var2")>
Public Property Var2 As List(Of String) = New List(Of String)({"default"})
End Class
Private DirectoryObjects As Dictionary(Of String, Dictionary(Of String, FileObj))
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim json = File.ReadAllText(jsonFile)
DirectoryObjects = JsonConvert.DeserializeObject(
Of Dictionary(Of String, Dictionary(Of String, FileObj)))(json)
End Sub
Private Sub btnAddFolder_Click(sender As Object, e As EventArgs) Handles btnAddFolder.Click
Dim dirPath = txtDirectory.Text
If DirectoryObjects.ContainsKey(dirPath) Then Return
Dim fileInfo As New Dictionary(Of String, FileObj)()
For Each file As String In Directory.GetFiles(dirPath)
fileInfo.Add(file, New FileObj() With {
.Var1 = "Something",
.Var2 = New List(Of String)({"Something", "Else"})
})
Next
DirectoryObjects.Add(dirPath, fileInfo)
' Now you can serialize and write to disc to preserve the changes
Dim dirInfoJson = JsonConvert.SerializeObject(DirectoryObjects)
File.WriteAllText(jsonFile, dirInfoJson)
End Sub
Private Sub btnEditFileInfo_Click(sender As Object, e As EventArgs) Handles btnEditFileInfo.Click
' Get the inner Dictionary using the Directory as the Key of the outer Dictionary
Dim fileObjects As Dictionary(Of String, FileObj) = DirectoryObjects(txtDirectory.Text)
' Get the FileObj object using the File as the Key of the inner Dictionary
Dim fileInfo As FileObj = fileObjects("[Selected File Path]")
' Add the new Values to var1 and var2
fileInfo.Var1 = txtDescription.Text
fileInfo.Var2 = New List(Of String)({txtDataVar2a.Text, txtDataVar2b.Text})
' You can serialize the Dictionary now or do it later
Dim dirInfoJson = JsonConvert.SerializeObject(DirectoryObjects)
File.WriteAllText(jsonFile, dirInfoJson)
End Sub