【问题标题】:Change values in JSON file (writing files)更改 JSON 文件中的值(写入文件)
【发布时间】:2014-03-08 20:17:31
【问题描述】:

我的应用程序的 Release 文件夹中有一个 settings.json 文件。我想做的是改变它的值,而不是暂时的,永久的。这意味着,删除旧条目,写一个新条目并保存它。

这是 JSON 文件的格式

{
"Admins":["234567"],
"ApiKey":"Text",
"mainLog": "syslog.log",
"UseSeparateProcesses": "false",
"AutoStartAllBots": "true",
"Bots": [
    {
        "Username":"BOT USERNAME",
        "Password":"BOT PASSWORD",
        "DisplayName":"TestBot",
        "Backpack":"",
        "ChatResponse":"Hi there bro",
        "logFile": "TestBot.log",
        "BotControlClass": "Text",
        "MaximumTradeTime":180,
        "MaximumActionGap":30,
        "DisplayNamePrefix":"[AutomatedBot] ",
        "TradePollingInterval":800,
        "LogLevel":"Success",
        "AutoStart": "true"
    }
]
}

假设我想更改密码值而不是 BOT PASSWORD 我希望它只是密码。我该怎么做?

【问题讨论】:

    标签: c# json


    【解决方案1】:

    这是一种简单且便宜的方法(假设 .NET 4.0 及更高版本):

    string json = File.ReadAllText("settings.json");
    dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
    jsonObj["Bots"][0]["Password"] = "new password";
    string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
    File.WriteAllText("settings.json", output);
    

    dynamic 的使用让您可以非常简单地索引到 json 对象和数组。但是,您确实会失去编译时检查。对于快速和肮脏的,它真的很好,但对于生产代码,您可能需要按照@gitesh.tyagi 的解决方案完全充实的类。

    【讨论】:

    • 它虽然缩进搞砸了..它都在 1 行..有什么办法解决这个问题??
    • 是的,JsonConvert.SerializeObject 可以采用第二个参数,Formatting.Indented。编辑答案。
    • 我到处搜索这个.. 谢谢。只有一个问题..为什么我在声明 jsonObj 时不能使用 var 而不是 dynamic?
    • @Alexander:因为 DeserializeObject 的返回类型是普通的旧 object。如果 json 的内容是一个简单的字典(没有嵌套数组或子对象),您可以使用 var jsonObj = JsonConvert.DeserializeObject<Dictionary<string,string>>(json); 并返回一个字典。或者,如果您只需要选择某些值,请参阅 this answer 了解另一种方法。
    • JsonConvert 删除“$type”属性。 JObject.Parse 没有。
    【解决方案2】:

    使用Newtonsoft.Json.Linq中的JObject类修改JSON值,无需提前知道JSON结构:

    using Newtonsoft.Json.Linq;
    
    string jsonString = File.ReadAllText("myfile.json");
    // Convert the JSON string to a JObject:
    JObject jObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString) as JObject;
    // Select a nested property using a single string:
    JToken jToken = jObject.SelectToken("Bots[0].Password");
    // Update the value of the property: 
    jToken.Replace("myNewPassword123");
    // Convert the JObject back to a string:
    string updatedJsonString = jObject.ToString();
    File.WriteAllText("myfile.json", updatedJsonString);
    

    示例:

    // This is the JSON string from the question
    string jsonString = "{\"Admins\":[\"234567\"],\"ApiKey\":\"Text\",\"mainLog\":\"syslog.log\",\"UseSeparateProcesses\":\"false\",\"AutoStartAllBots\":\"true\",\"Bots\":[{\"Username\":\"BOT USERNAME\",\"Password\":\"BOT PASSWORD\",\"DisplayName\":\"TestBot\",\"Backpack\":\"\",\"ChatResponse\":\"Hi there bro\",\"logFile\":\"TestBot.log\",\"BotControlClass\":\"Text\",\"MaximumTradeTime\":180,\"MaximumActionGap\":30,\"DisplayNamePrefix\":\"[AutomatedBot] \",\"TradePollingInterval\":800,\"LogLevel\":\"Success\",\"AutoStart\":\"true\"}]}";
    
    JObject jObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString) as JObject;
    
    // Update a string value:
    JToken jToken = jObject.SelectToken("Bots[0].Password");
    jToken.Replace("myNewPassword123"); 
    
    // Update an integer value:
    JToken jToken2 = jObject.SelectToken("Bots[0].TradePollingInterval");
    jToken2.Replace(555);
    
    // Update a boolean value:
    JToken jToken3 = jObject.SelectToken("Bots[0].AutoStart");
    jToken3.Replace(false);
    
    // Get an indented/formatted string:
    string updatedJsonString = jObject.ToString(); 
    
    //Output:
    //{
    //  "Admins": [
    //    "234567"
    //  ],
    //  "ApiKey": "Text",
    //  "mainLog": "syslog.log",
    //  "UseSeparateProcesses": "false",
    //  "AutoStartAllBots": "true",
    //  "Bots": [
    //    {
    //      "Username": "BOT USERNAME",
    //      "Password": "password",
    //      "DisplayName": "TestBot",
    //      "Backpack": "",
    //      "ChatResponse": "Hi there bro",
    //      "logFile": "TestBot.log",
    //      "BotControlClass": "Text",
    //      "MaximumTradeTime": 180,
    //      "MaximumActionGap": 30,
    //      "DisplayNamePrefix": "[AutomatedBot] ",
    //      "TradePollingInterval": 555,
    //      "LogLevel": "Success",
    //      "AutoStart": false
    //    }
    //  ]
    //}
    

    【讨论】:

      【解决方案3】:

      你必须有类来实例化 json 值:

      public class Bot
          {
              public string Username { get; set; }
              public string Password { get; set; }
              public string DisplayName { get; set; }
              public string Backpack { get; set; }
              public string ChatResponse { get; set; }
              public string logFile { get; set; }
              public string BotControlClass { get; set; }
              public int MaximumTradeTime { get; set; }
              public int MaximumActionGap { get; set; }
              public string DisplayNamePrefix { get; set; }
              public int TradePollingInterval { get; set; }
              public string LogLevel { get; set; }
              public string AutoStart { get; set; }
          }
          
       
      
         public class RootObject
          {
              public List<string> Admins { get; set; }
              public string ApiKey { get; set; }
              public string mainLog { get; set; }
              public string UseSeparateProcesses { get; set; }
              public string AutoStartAllBots { get; set; }
              public List<Bot> Bots { get; set; }
          }
      

      回答你的问题(未经测试的代码):

      //Read file to string
      string json = File.ReadAllText("PATH TO settings.json");
      
      //Deserialize from file to object:
      var rootObject = new RootObject();
      JsonConvert.PopulateObject(json, rootObject);
      
      //Change Value
      rootObject.Bots[0].Password = "password";
      
      // serialize JSON directly to a file again
      using (StreamWriter file = File.CreateText(@"PATH TO settings.json"))
      {
          JsonSerializer serializer = new JsonSerializer();
         serializer.Serialize(file, rootObject);
      }
      

      【讨论】:

      • 不好回答,下面sn-p中的代码不起作用。
      • 嗯,是的,当然你需要一个 RootObject 的实例来填充它的值。在答案中修复了这个问题。
      猜你喜欢
      • 1970-01-01
      • 2019-03-11
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 2015-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多