You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在嵌套JSON文档的数组中添加新对象(C#实现)

问题描述

免责声明:各位,C#并非我的专长;我通常是数据库开发人员。这段代码大多是我从各处拼凑来的,请手下留情。

我想要实现的功能是:打开用户指定的现有JSON文档,添加一个新对象到其中,然后将更新后的内容保存回文件。以下是一个符合实际结构的示例JSON,我需要为其中的"person"添加新的"car",新的车辆信息来自文本框和下拉框。

{"Name": "Bob Bob","City": "Louisville","State": "Kentucky","Address": "123 City Ln","Cars": [{"Make": "Ford","Model": "Explorer","Color": "White"},{"Make": "Dodge","Model": "Caravan","Color": "White"},{"Make": "Bat","Model": "Mobile","Color": "Black:"}],"Jobs": [{"Employer": "Walmart","Position": "Greeter","Pay": "$35,000","EndDate": "12/25/1999"},{"Employer": "Target","Position": "Cashier","Pay": "$32,000","EndDate": "1/1/2002"},{"Employer": "SkyNet","Position": "Programmer","Pay": "$86,000","EndDate": "5/8/2023"}]}

我已定义以下实体类:

public class Person
{    
    public string Name { get; set;}    
    public string City { get; set;}    
    public string State { get; set;}    
    public string Address { get; set;}    
    public Cars[] Cars {get; set;}    
    public Jobs[] Jobs {get; set;}
}

public class Cars
{    
    public string Make { get; set;}    
    public string Model { get; set;}    
    public string Color { get; set;}
}

public class Jobs
{    
    public string Employer { get; set;}    
    public string Position { get; set;}    
    public string Pay { get; set;}    
    public string EndDate { get; set;}
}

我的现有代码如下:

private void btnSaveUpdates_Click(object sender, EventArgs e)
{    
    string Make = cbMake.Text;    
    string Model = txtModel.Text;    
    string Color = cbColor.Text;    
    string filePath = txtFileLoc.Text;

    DoJSONWork(filePath, Make, Model, Color);
}

public static void DoJSONWork(string filePath, string Make, string Model, string Color)
{    
    var FileStream = File.OpenRead(filePath);

    using (StreamReader reader = new StreamReader(FileStream))    
    {        
        using (JsonTextReader JSONreader = new JsonTextReader(reader))        
        {            
            JSONreader.SupportMultipleContent = true;

            var serializer = new JsonSerializer();            
            while (JSONreader.Read())            
            {                
                if (JSONreader.TokenType == JsonToken.StartObject)                
                {                    
                    Person p = serializer.Deserialize<Person>(JSONreader);
                    Cars cars = p.Cars.FirstOrDefault(c => c.Make + c.Model + c.Color == Make + Model + Color);                    
                    if (cars == null)                    
                    {                        
                        cars = new Cars                        
                        {                            
                            Make = Make,                            
                            Model = Model,                            
                            Color = Color                        
                        };                        
                        p.Cars = p.Cars.Concat(new Cars[]                        
                        {                          
                            cars                        
                        }).ToArray();

                    }                
                }            
            }        
        }    
    }

    //I honestly don't know what to do next     
}

我正困惑于如何更新JSON文档中的"cars"数组,是否需要对整个JSON文档进行反序列化和序列化操作?


解决方案

没错,必须先把整个JSON文件反序列化成Person对象,修改完Cars数组后,再把整个对象序列化回文件。你的现有代码已经完成了反序列化和对象修改的步骤,缺的就是把修改后的对象写回文件的部分。

下面是调整后的完整代码,同时优化了几个细节:

private void btnSaveUpdates_Click(object sender, EventArgs e)
{    
    string make = cbMake.Text.Trim();    
    string model = txtModel.Text.Trim();    
    string color = cbColor.Text.Trim();    
    string filePath = txtFileLoc.Text.Trim();

    // 先校验输入有效性
    if (string.IsNullOrEmpty(make) || string.IsNullOrEmpty(model) || string.IsNullOrEmpty(color) || !File.Exists(filePath))
    {
        MessageBox.Show("请填写完整车辆信息,或确认文件路径有效");
        return;
    }

    UpdateCarInJson(filePath, make, model, color);
}

public static void UpdateCarInJson(string filePath, string make, string model, string color)
{
    try
    {
        // 1. 读取文件内容并反序列化为Person对象
        string jsonContent = File.ReadAllText(filePath);
        Person person = JsonConvert.DeserializeObject<Person>(jsonContent);

        // 2. 检查是否已存在相同车辆(改进判断逻辑,避免字符串拼接的潜在问题)
        bool carExists = person.Cars.Any(c => 
            string.Equals(c.Make, make, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(c.Model, model, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(c.Color, color, StringComparison.OrdinalIgnoreCase));

        if (!carExists)
        {
            // 创建新车辆并加入数组
            var newCar = new Cars
            {
                Make = make,
                Model = model,
                Color = color
            };

            // 用List处理添加操作更高效,再转回数组
            var carList = person.Cars.ToList();
            carList.Add(newCar);
            person.Cars = carList.ToArray();
        }

        // 3. 序列化修改后的对象并写入文件
        string updatedJson = JsonConvert.SerializeObject(person, Formatting.Indented);
        File.WriteAllText(filePath, updatedJson);

        MessageBox.Show("车辆信息更新成功");
    }
    catch (Exception ex)
    {
        MessageBox.Show($"操作失败:{ex.Message}");
    }
}

关键细节说明:

  • 用File.ReadAllText和File.WriteAllText简化文件操作,无需手动处理Stream和读写器
  • 判断重复车辆时,用StringComparison.OrdinalIgnoreCase忽略大小写(若需严格区分,可去掉该参数)
  • Formatting.Indented让生成的JSON带缩进,方便人工查看,不需要的话换成Formatting.None即可
  • 用List<T>.Add替代Concat,数组元素较多时性能更优

内容的提问来源于stack exchange,提问作者user1603398

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:42:22