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;
    }
}