如何在 C# 中删除 json 文件的元素

How remove element for json file in C#

我有 json 个文件 Users.json,我想删除一个元素。这是结构:

{
"1": {
    "Username": "1",
    "Name": "1",
    "AccessGroup": "Administrators"
},
"2": {
    "Username": "2",
    "Name": "2",
    "AccessGroup": "Supervisors"
},
"3": {
    "Username": "3",
    "Name": "3",
    "AccessGroup": "Administrators"
}

}

代码:

public void DeleteUser(Users.User user)
    {
        String filename = USERS_PATH;

        try
        {
            if (File.Exists(filename))
            {
                var data = DeserializeFromFile<Dictionary<String, User>>(USERS_PATH);
                foreach (var item in data)
                {         
                    if (user.Username == data[item.Key].Username)
                    {
                        data.Remove(user.Username);
                        break;

                    }

                }

            }

        }
        catch (Exception)
        {
            throw new ArgumentException("User has not deleted");
        }
    }

迭代后文件与之前相同。我哪里错了?提前致谢。

您必须将 data 保存到同一个文件中。

File.WriteAllText(USERS_PATH, JsonConvert.SerializeObject(data));
// I don't know what JSON parser you're using, but replace it with
// whatever that library provides for serializing data/saving to file :)

或类似这样的东西:)

基本上,您正在处理从文件中读取的内容的内存副本。如果你想像数据库一样使用 JSON,你可能想要编写某种 DAO/Repository 来公开基本的 CRUD 方法(打开文件 -> 执行更改 -> 写入文件)。

我可能是错的,但你不是必须通过它的键删除一个项目,而不是通过项目的 属性 吗?

所以:

data.Remove(item.Key);

这段代码有一些问题:

  • 将文件加载到对象后,Dictionary<string,User>不再对应于该文件:如果更新了字典,则文件不存在,反之亦然,您需要再次序列化数据并将其保存到文件中:

    String encoded = JsonConvert.SerializeObject(data);
    System.IO.File.WriteAllText(filename,encode);
    
  • Dictionary.Remove 要求提供一个密钥,您可以使用用户名删除,但不能保证(尤其是在您的示例文件中),密钥就是用户名。结果是什么都没有被删除。所以你应该使用:

    data.Remove(item.Key);
    

    而不是:

    data.Remove(user.Username);
    
  • 接下来,您不应该删除迭代器中的数据。虽然这在这种情况下有效,因为您做了一个中断,但一般来说,这样做是一个 非常糟糕的主意 ,因为大多数枚举器并非设计用于枚举不断变化的集合。在这种情况下,您可以存储对要删除的密钥的引用:

    var torem = null;
    foreach (var item in data) {         
        if (user.Username == data[item.Key].Username) {
            torem = item.Key;
            break;
        }
    }
    if(torem != null) {
        data.Remove(torem);
    }
    
  • 您还可以通过使用 item.Value 而不是 data[item.Key].Username 来节省一些 CPU 周期,因为您所做的是查找您已经拥有的值指针所以使用:

    if(user.Username == item.Value.Username)
    

    而不是:

    if (user.Username == data[item.Key].Username)