C# JSON.net 未正确创建对象作为反序列化字典中的值
C# JSON.net not properly creating objects as values in dictionary on deserialization
我有一个 "Settings" class,其中包含一个值为 "InputBindings" class 的字典。使用 JSON.NET,它正确地将设置数据 writes/serializes 放入 .json 文件中,但是在 reading/deserializing 文件中它没有正确创建对象。
我试过使用"TypeNameHandling"和"Custom JsonConverter T",但我不确定我是否正确使用它们,但并没有像我尝试的那样解决我的问题。我一直在查看文档,但我不确定此时该尝试什么。我不确定为什么它能正确序列化所有内容但不能正确反序列化。
这里是相关的 classes,去掉了一些不必要的东西,比如枚举、日志记录和我分配给字典的默认值。
public static class PlayerInput
{
public static Settings InputSettings { get; private set; } = new Settings();
public static void Initialize()
{
SetSettingsToDefaults();
FileOps.WriteSettingsToFile();
FileOps.ReadSettingsFromFile();
}
}
public class Settings
{
public PlayerInput.MovementStyleEnum MovementStyle { get; set; } = PlayerInput.MovementStyleEnum.ScreenSpace;
public PlayerInput.InputModeEnum InputMode { get; set; } = PlayerInput.InputModeEnum.KeyboardAndMouse;
public Dictionary<InputBinding.GameInputsEnum, InputBinding> InputBindingsKBM { get; set; } = new Dictionary<InputBinding.GameInputsEnum, InputBinding>();
public Dictionary<InputBinding.GameInputsEnum, InputBinding> InputBindingsController { get; set; } = new Dictionary<InputBinding.GameInputsEnum, InputBinding>();
}
public class InputBinding
{
public GameInputsEnum InputName { get; private set; }
public InputTypeEnum InputType { get; private set; }
public string InputButton { get; private set; }
public KeyCode InputKey { get; private set; }
public int InputMouseButton { get; private set; }
public InputBinding(GameInputsEnum _inputName, InputTypeEnum _inputType, string _inputButton, KeyCode _inputKey, int _mouseButton)
{
this.InputName = _inputName;
this.InputType = _inputType;
this.InputButton = _inputButton;
this.InputKey = _inputKey;
this.InputMouseButton = _mouseButton;
}
}
public static class FileOps
{
private const string SettingsFilePath = "Settings.json";
public static bool ReadSettingsFromFile()
{
if(File.Exists(SettingsFilePath) == false)
{
return false;
}
else
{
Settings settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(SettingsFilePath));
// Looping through the dictionaries in settings here is where the objects don't seem to properly reflect what is written in the .json file
return true;
}
}
public static void WriteSettingsToFile()
{
File.WriteAllText(SettingsFilePath, JsonConvert.SerializeObject(PlayerInput.InputSettings, Formatting.Indented));
}
}
FileOps.WriteSettingsToFile() 正确地创建了一个 .json 文件,看起来应该是这样。参见 https://pastebin.com/DZ5paXgY
当我使用一些 foreach 循环遍历 FileOps.ReadSettingsFromFile() 读取的设置时,它表明它没有在字典中正确创建 InputBinding 对象。参见 https://pastebin.com/FP2DaAaE
字典的键已正确填充,但值是为每个键重复的相同默认值。
例如:
"Pause : Submit, , None, 0"
第 6 行的输出应该类似于
"Pause : Pause, , 27, 0" 反映了您从 .json 文件的第 19 行开始看到的内容。
首先,不要在参数名称中使用下划线。下划线前缀应该只用于字段而不是参数。其次,由于下划线,JSON.NET 无法将 JSON 属性映射到您的构造函数参数。
去掉下划线,JSON.NET就可以把JSON映射到参数上了。
public class InputBinding
{
public GameInputsEnum InputName { get; private set; }
public InputTypeEnum InputType { get; private set; }
public string InputButton { get; private set; }
public KeyCode InputKey { get; private set; }
public int InputMouseButton { get; private set; }
public InputBinding(GameInputsEnum inputName, InputTypeEnum inputType, string inputButton, KeyCode inputKey, int mouseButton)
{
this.InputName = inputName;
this.InputType = inputType;
this.InputButton = inputButton;
this.InputKey = inputKey;
this.InputMouseButton = mouseButton;
}
}
我有一个 "Settings" class,其中包含一个值为 "InputBindings" class 的字典。使用 JSON.NET,它正确地将设置数据 writes/serializes 放入 .json 文件中,但是在 reading/deserializing 文件中它没有正确创建对象。
我试过使用"TypeNameHandling"和"Custom JsonConverter T",但我不确定我是否正确使用它们,但并没有像我尝试的那样解决我的问题。我一直在查看文档,但我不确定此时该尝试什么。我不确定为什么它能正确序列化所有内容但不能正确反序列化。
这里是相关的 classes,去掉了一些不必要的东西,比如枚举、日志记录和我分配给字典的默认值。
public static class PlayerInput
{
public static Settings InputSettings { get; private set; } = new Settings();
public static void Initialize()
{
SetSettingsToDefaults();
FileOps.WriteSettingsToFile();
FileOps.ReadSettingsFromFile();
}
}
public class Settings
{
public PlayerInput.MovementStyleEnum MovementStyle { get; set; } = PlayerInput.MovementStyleEnum.ScreenSpace;
public PlayerInput.InputModeEnum InputMode { get; set; } = PlayerInput.InputModeEnum.KeyboardAndMouse;
public Dictionary<InputBinding.GameInputsEnum, InputBinding> InputBindingsKBM { get; set; } = new Dictionary<InputBinding.GameInputsEnum, InputBinding>();
public Dictionary<InputBinding.GameInputsEnum, InputBinding> InputBindingsController { get; set; } = new Dictionary<InputBinding.GameInputsEnum, InputBinding>();
}
public class InputBinding
{
public GameInputsEnum InputName { get; private set; }
public InputTypeEnum InputType { get; private set; }
public string InputButton { get; private set; }
public KeyCode InputKey { get; private set; }
public int InputMouseButton { get; private set; }
public InputBinding(GameInputsEnum _inputName, InputTypeEnum _inputType, string _inputButton, KeyCode _inputKey, int _mouseButton)
{
this.InputName = _inputName;
this.InputType = _inputType;
this.InputButton = _inputButton;
this.InputKey = _inputKey;
this.InputMouseButton = _mouseButton;
}
}
public static class FileOps
{
private const string SettingsFilePath = "Settings.json";
public static bool ReadSettingsFromFile()
{
if(File.Exists(SettingsFilePath) == false)
{
return false;
}
else
{
Settings settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(SettingsFilePath));
// Looping through the dictionaries in settings here is where the objects don't seem to properly reflect what is written in the .json file
return true;
}
}
public static void WriteSettingsToFile()
{
File.WriteAllText(SettingsFilePath, JsonConvert.SerializeObject(PlayerInput.InputSettings, Formatting.Indented));
}
}
FileOps.WriteSettingsToFile() 正确地创建了一个 .json 文件,看起来应该是这样。参见 https://pastebin.com/DZ5paXgY
当我使用一些 foreach 循环遍历 FileOps.ReadSettingsFromFile() 读取的设置时,它表明它没有在字典中正确创建 InputBinding 对象。参见 https://pastebin.com/FP2DaAaE
字典的键已正确填充,但值是为每个键重复的相同默认值。
例如:
"Pause : Submit, , None, 0"
第 6 行的输出应该类似于
"Pause : Pause, , 27, 0" 反映了您从 .json 文件的第 19 行开始看到的内容。
首先,不要在参数名称中使用下划线。下划线前缀应该只用于字段而不是参数。其次,由于下划线,JSON.NET 无法将 JSON 属性映射到您的构造函数参数。
去掉下划线,JSON.NET就可以把JSON映射到参数上了。
public class InputBinding
{
public GameInputsEnum InputName { get; private set; }
public InputTypeEnum InputType { get; private set; }
public string InputButton { get; private set; }
public KeyCode InputKey { get; private set; }
public int InputMouseButton { get; private set; }
public InputBinding(GameInputsEnum inputName, InputTypeEnum inputType, string inputButton, KeyCode inputKey, int mouseButton)
{
this.InputName = inputName;
this.InputType = inputType;
this.InputButton = inputButton;
this.InputKey = inputKey;
this.InputMouseButton = mouseButton;
}
}