更改JSON文件中的值(写入文件)

时间:2014-02-11 06:57:41

标签: c# json

我的应用程序的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我希望它只是密码。我该怎么做?

4 个答案:

答案 0 :(得分:32)

这是一个简单的&廉价的方法(假设.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 :(得分:9)

您必须有类将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:
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);
}

答案 2 :(得分:0)

使用JObject中的Newtonsoft.Json.Linq类在不提前知道JSON结构的情况下进行操作:

using Newtonsoft.Json.Linq;

string jsonString = File.ReadAllText("myfile.json");
JObject jObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString) as JObject;
// Select a nested property using a single string:
JToken jToken = jObject.SelectToken("Bots[0].Password"); 
jToken.Replace("password");
string updatedJsonString = jObject.ToString();
File.WriteAllText("myfile.json", updatedJsonString);

示例:

// This is the JSON 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("password"); 

// 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 :(得分:-1)

我已经可以使用上面的信息使程序的2 / 3rds有效。我正在更新三个值。

.json格式代码段:

{ “版本”:“ 1.0.0”, “ SignBatches”:[ { “ SourceRootDirectory”:“ c:\ red”, “ DestinationRootDirectory”:“ d:\ green”, “ SignRequestFiles”:[ { “ SourceLocation”:“ billboard-GS_PariahHeart-v1.lzp” } ]

有效的代码:

jsonObj [“ SignBatches”] [0] [“ SourceRootDirectory”] = Path.GetDirectoryName(args [0]);

jsonObj [“ SignBatches”] [0] [“ DestinationRootDirectory”] = Path.GetDirectoryName(args [1]);

代码失败:

jsonObj [“ SignRequestFiles”] [0] [“ SourceLocation”] = Path.GetFileName(args [0]);

请注意,这试图更新.json文件中嵌套对象的值。前两行正在更新相似的值,但它们在顶层。

生成的错误是:

未处理的异常。 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法对空引用执行运行时绑定