You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于C# Newtonsoft JSON实现用户被动技能的JSON分类存储

问题

我正在开发一款基于《龙珠Z:爆裂大战》(Dokkan Battle)的Discord Bot小游戏,支持用户创建自定义被动技能,可通过指令查看对应属性。需要将这些被动技能数据按指定JSON格式存储(包含userPassiveStorage说明与members数组),但当前代码生成的JSON格式错误(仅单行存储)。现需实现向members数组添加新成员的功能,同时希望了解更易检索的存储方案。

当前代码:

public void StoreUserPassives(DokkanUserPassiveBuilder classObj) 
{
    using (StreamWriter sw = new StreamWriter("UserPassivesStorage.json")) 
    {
        JsonSerializer serializer = new JsonSerializer();
        List<DokkanUserPassiveBuilder> data = new List<DokkanUserPassiveBuilder>();
        data.Add(classObj);

        string json = JsonConvert.SerializeObject(data.ToArray(), Formatting.Indented);
        serializer.Serialize(sw, json);
    }
}

目标JSON格式:

{
  "userPassiveStorage": "Storage for user created passives using /passivecreator",
  "members": [
      {
          "passiveName": "",
          "leaderName": "",
          "unitHP": 0,
          "unitATK": 0,
          "unitDEF": 0,
          "leaderValue": 0,
          "passiveATK": 0,
          "passiveDEF": 0,
          "supportBuff": 0,
          "links": ""
      }
  ]
}

解决方案

一、修复JSON格式并实现添加成员功能

首先得创建一个匹配目标JSON结构的实体类,不能直接序列化列表:

// 对应整体存储结构的实体类
public class UserPassiveStorage
{
    [JsonProperty("userPassiveStorage")]
    public string Description { get; set; } = "Storage for user created passives using /passivecreator";

    [JsonProperty("members")]
    public List<DokkanUserPassiveBuilder> Members { get; set; } = new List<DokkanUserPassiveBuilder>();
}

// 确保DokkanUserPassiveBuilder的属性和目标JSON字段一一对应
public class DokkanUserPassiveBuilder
{
    [JsonProperty("passiveName")]
    public string PassiveName { get; set; } = "";

    [JsonProperty("leaderName")]
    public string LeaderName { get; set; } = "";

    [JsonProperty("unitHP")]
    public int UnitHP { get; set; }

    [JsonProperty("unitATK")]
    public int UnitATK { get; set; }

    [JsonProperty("unitDEF")]
    public int UnitDEF { get; set; }

    [JsonProperty("leaderValue")]
    public int LeaderValue { get; set; }

    [JsonProperty("passiveATK")]
    public int PassiveATK { get; set; }

    [JsonProperty("passiveDEF")]
    public int PassiveDEF { get; set; }

    [JsonProperty("supportBuff")]
    public int SupportBuff { get; set; }

    [JsonProperty("links")]
    public string Links { get; set; } = "";
}

然后修改存储方法,实现读取现有数据→添加新成员→写入文件的完整逻辑:

public void StoreUserPassives(DokkanUserPassiveBuilder newPassive)
{
    UserPassiveStorage storage = null;
    string filePath = "UserPassivesStorage.json";

    // 读取已有文件(如果存在)
    if (File.Exists(filePath))
    {
        string existingJson = File.ReadAllText(filePath);
        storage = JsonConvert.DeserializeObject<UserPassiveStorage>(existingJson);
    }
    else
    {
        // 文件不存在就初始化新的存储结构
        storage = new UserPassiveStorage();
    }

    // 把新被动技能加入members数组
    storage.Members.Add(newPassive);

    // 序列化并写入格式化后的JSON
    string formattedJson = JsonConvert.SerializeObject(storage, Formatting.Indented);
    File.WriteAllText(filePath, formattedJson);
}

关键修复说明

  • 之前的代码错误地把序列化后的JSON字符串再次序列化,导致输出的是转义后的单行内容,现在直接序列化实体类并通过Formatting.Indented生成格式化的JSON。
  • 新增了读取现有数据的逻辑,避免每次覆盖整个文件,而是在原有数据基础上追加新成员。

二、更易检索的存储方案

如果需要频繁检索被动技能(比如按技能名称、创建者ID查找),纯JSON文件的效率会随数据量增加下降,推荐以下几种方案:

1. 本地SQLite数据库

SQLite是轻量级本地数据库,适合小型Bot应用:

  • 可以为被动技能创建数据表,给常用检索字段(比如passiveName、userId)设置索引,大幅提升检索速度。
  • 支持SQL查询,方便做复杂的筛选、排序操作。
  • 示例表结构:
CREATE TABLE UserPassives (
    Id INTEGER PRIMARY KEY AUTOINCREMENT,
    PassiveName TEXT NOT NULL,
    LeaderName TEXT,
    UnitHP INTEGER,
    UnitATK INTEGER,
    UnitDEF INTEGER,
    LeaderValue INTEGER,
    PassiveATK INTEGER,
    PassiveDEF INTEGER,
    SupportBuff INTEGER,
    Links TEXT,
    UserId TEXT NOT NULL -- 记录创建者ID,方便按用户检索
);
CREATE INDEX idx_passive_name ON UserPassives(PassiveName);
CREATE INDEX idx_user_id ON UserPassives(UserId);

2. LiteDB文档型存储

LiteDB是.NET平台的轻量级文档数据库,类似MongoDB但无需服务器:

  • 可以把每个被动技能作为独立文档存储,支持按字段创建索引和查询。
  • 操作比SQLite更灵活,不用写SQL语句。

3. 优化JSON文件存储(适合小数据量)

如果坚持用JSON文件,可以做以下优化:

  • 按用户ID分文件存储,比如每个用户的被动技能单独存一个JSON文件。
  • 在内存中维护一个字典索引,比如Dictionary<string, List<DokkanUserPassiveBuilder>>,键为用户ID,值为该用户的技能列表,每次修改后同步到JSON文件,检索时直接通过键获取,不用遍历整个数组。

内容的提问来源于stack exchange,提问作者user11057786

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:55:17