如何向现有的JSON文件中添加新对象

14
我正在尝试自动化向现有的JSON文件中添加新对象。我在网上找了很多地方,但只找到了添加数据和其他内容,而不是整个对象。这是我想要编辑的文件的样子:
[
    {"id":"123","name":"carl"}
]

我想去
[
     {"id":"123","name":"carl"},
     {"id":"1234","name":"carl2"}
]

谢谢大家的回答,但我觉得并不是每个人都完全理解我的意思。我尝试了一些答案,但是结果是这样的:
[
    "{\"id\":\"123\",\"name\":\"carl\"}"
]"{\"id\":\"1234\",\"name\":\"carl2\"}"

我想要中括号[]之间的所有内容。

4
将数据反序列化成 C# 数据类型(或 JObjectdynamic 等),向列表添加一个新项,然后将其重新序列化为字符串? - crashmstr
6个回答

18
如果你使用json.NET,你可以轻松地反序列化和序列化JSON。
var list = JsonConvert.DeserializeObject<List<Person>>(myJsonString);
list.Add(new Person(1234,"carl2");
var convertedJson = JsonConvert.SerializeObject(list, Formatting.Indented);

这个实际上会保持顺序吗? - David Pine
既然 JSON 中的顺序不能保证,那么这并不重要。 - PRMan
1
@PRMan JSON保留数组项的顺序,但不保留字典项的顺序。 - Akash Agarwal
2
如果您有一个大的Json文件,这是一个好的选择吗? - Ahune ajé o ahe

8
使用Json.Net
//load from file
var initialJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";

var array = JArray.Parse(initialJson);

var itemToAdd = new JObject();
itemToAdd["id"] = 1234;
itemToAdd["name"] = "carl2";
array.Add(itemToAdd);

var jsonToOutput = JsonConvert.SerializeObject(array, Formatting.Indented);

//save to file here

使用这种方法不需要强类型对象。你可以替换掉下面的这段内容:
//load from file
var initialJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";

随着

var initialJson = File.ReadAllText(@"c:\myjson.json")

从文本文件加载json的方法

4
比起对可能是大文件的字符串进行串行化/反串行化的方法,更好的性能解决方案是打开一个文件流,从结尾往前找一个字符,然后将新对象进行序列化和写入数组,接着写入一个闭合括号。请参考这个问题:C# 如何从文本文件中删除最后两个字符并将其写入同一行的末尾?,我会将代码复制在这里 - 您已经知道如何将对象序列化并编码为字节。
using(var fs = new FileStream("file.json")) {    
    fs.Seek(-1,SeekOrigin.End);        
    fs.Write(mySerializedJSONObjAsBytes,0,mySerializedJSONObjAsBytes.Length); // include a leading comma character if required
    fs.Write(squareBracketByte, 0, 1);
    fs.SetLength(fs.Position); //Only needed if new content may be smaller than old
}

对不起,我没有测试过这些内容,只是凭借自己的经验说出来的。专业技巧:将FileStream包装在StreamWriter中,这样就可以直接编写字符串。


这是最佳答案,因为其他所有答案都会反序列化/序列化整个JSON文件,仅仅为了向列表中添加一个元素,这是不必要的,并且如果文件很大和/或您需要频繁添加新元素,则会影响性能。 - Adrian

2
您可以创建一个方法:
public string AddObjectsToJson<T>(string json, List<T> objects)
{
    List<T> list = JsonConvert.DeserializeObject<List<T>>(json);
    list.AddRange(objects);
    return JsonConvert.SerializeObject(list);
}

然后像这样使用它:
string baseJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";
List<Person> personsToAdd = new List<Person>() { new Person(1234,"carl2") };

string updatedJson = AddObjectsToJson(baseJson, personsToAdd);

2
由于您正在尝试将一个对象列表添加到另一个列表中,所以应该使用AddRange()而不是Add()方法。 - Abhishek

1
这是一个示例:

这将是一个样本给你看:

var list = JsonConvert.DeserializeObject<List<Example>>(json);
    Example example = new Example();
    example.name = "Product2";
    example.id="1";
    list.Add(example);
    
    string output = JsonConvert.SerializeObject(list);
    
    public class Example
    {
        public string id {get;set;}
        public string name { get; set; }
        
    }

非常明确的回答。非常感谢。 - alvinchesaro

0

我已经寻找这个确切问题的解决方案一个星期了。我终于弄清楚如何将其附加到现有的 JSON 数组中,而不是在数组之后作为单独的对象添加。确保使用 WriteAllText 而不是 AppendAllText。以下是我的做法:

JArray array = JsonConvert.DeserializeObject<JArray (jsonFile);

JObject obj = new JObject();
obj.Add("ID", "123");
obj.Add("Name", "Brian");

array.Add(obj);

var jsonToOutput = JsonConvert.SerializeObject(array, Formatting.Indented);
File.WriteAllText("fileName.json", jsonToOutput);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接