查找JSON条目并添加嵌套元素

时间:2016-08-24 10:07:58

标签: c# json json.net

我有一个.json文件,如下所示:

[
  {
    "username": "John",
    "currency": 8,
    "pulls": 
    [
      {
        "character": "person"
      },
      {
        "character": "loved one"
      }
    ]
  },
  {
    "username": "Mike",
    "currency": 2,
    "pulls": 
    [
      {
        "character": "noone" 
      }
    ]
  },
  {
    "username": "Clara",
    "currency": 5,    
    "pulls": 
    [
      {
        "character": "someone" 
      }
    ]
  }
] 

到目前为止我设法做的是修改“货币”:

    bool userExists = false;
    string jsonPointsString = File.ReadAllText(userPath);
    dynamic jsonObjects = JsonConvert.DeserializeObject(jsonPointsString);
    foreach (var jsonObject in jsonObjects)
    {
        if (jsonObject["username"] == user)
        {
            jsonObject["currency"] += value;
            string output = JsonConvert.SerializeObject(jsonObjects, Formatting.Indented);
            File.WriteAllText(userPath, output);
            userExists = true;
        }
    }

除了从头开始添加一个全新的条目:

    JsonCollection.User user = new JsonCollection.User();
    user.username = username;
    user.currency = 10;
    using (StreamReader r = new StreamReader(userPath))
    {
        string json = r.ReadToEnd();
        List<JsonCollection.User> users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(json);
        users.Add(user);
        newJson = JsonConvert.SerializeObject(users, Formatting.Indented);
    }
    File.WriteAllText(userPath, newJson);

然而,无论我尝试什么,我都无法添加另一个元素来“拉”。我的想法是我用一个用户名和一个拉,两个字符串调用一个函数。根据用户名变量,我必须找到相应的Json Entry,并根据pull变量在“pulls”树中创建一个新条目。这就是我能想到的:

    public void AddPullToUser(string user, string newPull)
    {
        user = "Mike";  //test value

        string jsonPointsString = File.ReadAllText(userPath);
        dynamic jsonObjects = JsonConvert.DeserializeObject(jsonPointsString);
        foreach (var jsonObject in jsonObjects)
        {
            if (jsonObject["username"] == user)
            {
                //jsonObject["pulls"] = newPull;

                JsonCollection.Character pull = new JsonCollection.Character();
                pull.character = newPull;
                jsonObject["pulls"] = pull;

                string output = JsonConvert.SerializeObject(jsonObjects, Formatting.Indented);
                File.WriteAllText(userPath, output);

            }
        }
    }

如果我这样做,系统无法将JsonCollection转换为JArray但不使用JArray我不明白如何找到特定的用户树。 在第二步中,必须进一步扩展以不产生重复的“拉动”,但首先必须这样做。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

像这样 -

var json = "[{'username':'John','currency':8,'pulls':[{'character':'person'},{'character':'loved one'}]},{'username':'Mike','currency':2,'pulls':[{'character':'noone'}]},{'username':'Clara','currency':5,'pulls':[{'character':'someone'}]}]";
var obj = JsonConvert.DeserializeObject<List<RootObject>>(json);
var o = obj.FindIndex(a => a.username == "Mike");
obj[o].pulls.AddRange(new List<Pull>{
        new Pull{
            character = "Modified"
        }
    });

Console.WriteLine(JsonConvert.SerializeObject(obj));

哪里

public class Pull
{
    public string character { get; set; }
}

public class RootObject
{
    public string username { get; set; }
    public int currency { get; set; }
    public List<Pull> pulls { get; set; }
}

或者,您可能对JSON Merge

感兴趣

可能的解决方案如下 -

var json = "[{'username':'John','currency':8,'pulls':[{'character':'person'},{'character':'loved one'}]},{'username':'Mike','currency':2,'pulls':[{'character':'noone'}]},{'username':'Clara','currency':5,'pulls':[{'character':'someone'}]}]";
var obj = JArray.Parse(json);
var idx = obj.IndexOf(obj.FirstOrDefault(a => a["username"].ToString() == "Mike"));     
((JArray)obj[idx]["pulls"]).Add(JObject.Parse(@"{
        'character': 'new one'
    }"));
Console.WriteLine(obj[idx]);
/*output - 
 {
   "username": "Mike",
   "currency": 2,
   "pulls": [
     {
        "character": "noone"
     },
     {
        "character": "new one"
     }
  ]
} */

答案 1 :(得分:0)

经过一些研究和你的帮助后,我首先能够将与Json的所有交互改变为相同的代码风格。

新条目已更改为:

    public void CreateUser(string username)
    {
        try
        {
            string jsonUserString = File.ReadAllText(userPath);
            var users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(jsonUserString);
            users.AddRange(new List<JsonCollection.User> { new JsonCollection.User { username = username, currency = 10, pulls = new List<JsonCollection.Character> { new JsonCollection.Character { character = "TemmieHYPE" } } } });
            string output = JsonConvert.SerializeObject(users, Formatting.Indented);
            File.WriteAllText(userPath, output);
        }
        catch
        {
            Console.WriteLine("Error on CreateUser");
        }
    }

更新已更改为:

    public void UpdateUserStats(string username, decimal value, int selection)
    {
        try
        {
            string jsonUserString = File.ReadAllText(userPath);
            var users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(jsonUserString);
            int user = users.FindIndex(a => (a.username == username));
            if (user != -1)
            {
                switch (selection)
                {
                    case 1:
                        users[user].currency += value;
                        break;
                    case 2:
                        users[user].secondsOnline += value;
                        break;
                    default:
                        break;
                }

                string output = JsonConvert.SerializeObject(users, Formatting.Indented);
                File.WriteAllText(userPath, output);

                //AddPullToUser(username, DateTime.Now.ToString());  //remove on live
            }
            else
            {
                CreateUser(username);
            }
        }
        catch 
        {
            Console.WriteLine("Error on UpdateCurrency");
        }
    }

最重要的是,添加拉动命令将嵌套元素添加到Json现在可以使用以下代码:

    public void AddPullToUser(string username, string pulledCharacter)
    {
        string jsonUserString = File.ReadAllText(userPath);
        var users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(jsonUserString);
        int alreadyPulled = users.FindIndex(a => (a.username == username) && (a.pulls.FindIndex(b => b.character == pulledCharacter) > 0));
        if (alreadyPulled == -1)
        {
            int user = users.FindIndex(a => (a.username == username));
            users[user].pulls.AddRange(new List<JsonCollection.Character> { new JsonCollection.Character { character = pulledCharacter } });
            string output = JsonConvert.SerializeObject(users, Formatting.Indented);
            File.WriteAllText(userPath, output);
        }
    }

添加&#34; if(alreadyPulled == -1)&#34;重复的拉动也不会被添加到Json文件中。