Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
设置嵌套JSON对象的属性_Json_Vb.net_Winforms_Json.net - Fatal编程技术网

设置嵌套JSON对象的属性

设置嵌套JSON对象的属性,json,vb.net,winforms,json.net,Json,Vb.net,Winforms,Json.net,我是JSON.Net的新手,还没有弄清楚如何将JSON的嵌套对象作为JObject。我使用一个文件来存储JSON对象,然后将所做的更改写回该文件 背景 我正在尝试制作一个应用程序,用户在其计算机上选择一个文件夹,该应用程序将该文件夹及其所有文件枚举到一个JSON对象中。然后,用户可以选择这些文件中的任何一个,并设置要保存到JSON文件的文件的值。到目前为止,我已经实现了将目录结构/包含的文件生成为JSON并将其保存到文件中的功能,但我一直在尝试访问JSON的嵌套对象以设置属性值 到目前为止我的代

我是JSON.Net的新手,还没有弄清楚如何将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