【问题标题】:How to deserialize json?如何反序列化json?
【发布时间】:2015-07-12 15:12:50
【问题描述】:

我的应用程序使用配置来管理游戏的模组包,因此配置加载器是这样工作的:

这是configurations.json:

{
"GameDirectory": "C:\\Users\\username\\AppData\\Roaming\\.mp-craft-project",
"Configurations": {
    "MP-Craft-Default": {
        "Name": "MP-Craft-Default",
        "JavaPath": "C:\\ProgramFiles\\Java\\jre-xxx\\bin\\javaw.exe",
        "FullScreenMode": "Enabled",
        "ModLoader": "MCF_1.0"
    },
    "New-Configuration": {
        "Name": "New-Configuration",
        "JavaPath": "C:\\ProgramFiles\\Java\\jre-xxx\\bin\\javaw.exe",
        "FullScreenMode": "Enabled",
        "ModLoader": "MCF_2.0"
    }
  }
}

并且此 json 中的字符串(例如 modloader 或 fullscreenmode)可以是相同或不同(未知)的变体。 我想按名称加载所有配置,并加载所选配置的设置。有人可以帮我吗,我该如何反序列化这个json。

我正在使用Newtonsoft.Json 进行反序列化。

感谢帮助。

【问题讨论】:

  • 您要反序列化哪个?在名称中允许空格可能会导致问题:“Example Config”不会匹配“Example_Config”
  • 您是从其他地方得到这些还是这些是您的发明?我问是因为将它们组合起来似乎比尝试从 A 中的文本中找到 B 更容易
  • 所以我需要做的是:加载配置,然后加载所选配置的设置。
  • 好吧,与其将实际配置保存在不同的 json 中,不如将名称保存在 A 中,保存实际配置...像这样:pastebin.com/87WC5z2s 你所拥有的有些问题 -该字符串数组包含 2 条信息 - 0、2、4... 是“名称”,1、3、5 将是文件名 - 难以管理。此外,如果这只是您的本地存储并且您没有将它们发送到任何地方,那么 XML 序列化器会更合适
  • JSON 更适合数据交换,如果是本地存储,XML 序列化会更好。无论哪种方式,编辑您的问题以获得您想要的答案

标签: .net json vb.net serialization token


【解决方案1】:

您需要 2 个类,一个包含 Config 集合和各种“全局”数据,然后是一个用于项目的类:

Public Class Configs
    Public Property GameDirectory As String

    Public Property Configurations As Dictionary(Of String, ConfigItem)

    Public Sub New()
        Configurations = New Dictionary(Of String, ConfigItem)
    End Sub
End Class

Public Class ConfigItem
    Public Property Name As String

    Public Property JavaPath As String
    Public Property FullScreenMode As String            ' I would use Boolean
    Public Property ModLoader As String
End Class

创建集合类并将配置项存储到它:

Imports System.Environment
...
Dim myCfgs As New Configs
myCfgs.GameDirectory = Path.Combine(Environment.GetFolderPath(SpecialFolder.ApplicationData), ".mp-craft-project")

Dim p As New ConfigItem
p.Name = "Ziggy"
p.FullScreenMode = "Enabled"
p.ModLoader = "MCF_1.0"
p.JavaPath = "C:\ProgramFiles\Java\jre-xxx\bin\javaw.exe"

' add this item to the collection
myCfgs.Configurations.Add(p.Name, p)

' add another, create a new ConfigItem object
p = New ConfigItem
p.Name = "Hoover"
p.FullScreenMode = "Enabled"
p.ModLoader = "MCF_2.0"
p.JavaPath = "...javaw.exe"
myCfgs.Configurations.Add(p.Name, p)

要从集合中取出一个来使用:

Dim thisCfg As ConfigItem = myCfgs.Configurations("Ziggy")
Console.WriteLine("Name: {0}, JavaPath: {1}, ModLoader: {2}",
                  thisCfg.Name, thisCfg.JavaPath, thisCfg.ModLoader)

输出:

名称:Ziggy,JavaPath:C:\ProgramFiles\Java\jre-xxx\bin\javaw.exe,ModLoader:MCF_1.0

序列化/保存:

' save all configs to disk:
Dim jstr = JsonConvert.SerializeObject(myCfgs)
File.WriteAllLines(saveFileName, jstr)

要加载最后一组保存的配置:

' load the text, then deserialize to a Configs object:
Dim jstr = File.ReadAllText(saveFileName)
Dim myCfgs As Configs = JsonConvert.DeserializeObject(Of Configs)(jstr)

有一些改进和注意事项:

  1. 存储路径文字时,不要使用转义字符。使用"C:\path\file\..." 而不是"C:\\path\\file\\..."。序列化程序添加了额外的\s
  2. 如前所述,我将使用布尔值,而不是解析 Enabled 来确定全屏。
  3. 我会避免在名称和键中使用破折号、斜线和空格等
  4. 有些东西可能比 Enums 或 Types 更好,例如 "MCF_1.0",所以你不必解析它来确定它是 11.1 还是 2.0
  5. 由于配置位于字典中,如果您不熟悉这些配置,可能需要了解如何使用它们。

【讨论】:

  • 您应该发布一个新问题,以便代码格式正确 - 我看不懂。但是,由于不是数组,所以需要使用For Each
猜你喜欢
  • 1970-01-01
  • 2014-02-27
  • 2015-05-19
  • 1970-01-01
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多