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

如何在C#中修改JSON文件的嵌套对象与数组值?

修改JSON嵌套对象与数组元素的C#实现

针对当前仅能修改JSON顶层字段的问题,以下是几种基于Newtonsoft.Json(Json.NET)的解决方案,可实现嵌套对象、深层属性及数组元素的修改:

原问题回顾

JSON结构

{
  "externalReference": "Integrator Reference",
  "proposalType": "Private Individual",
  "dealer": {
    "dealerID": 9344
  },
  "financeDetails": {
    "type": "HP",
    "cashDeposit": 111,
    "settlement": 11,
    "partExchange": 22,
    "term": 72,
    "apr": 12.9,
    "loanamount": 0.0,
    "distanceSelling": true,
    "vehicleAsset": {
      "type": "Used",
      "class": "Car",
      "source": "UK",
      "purpose": "Social",
      "vrm": "string",
      "dateOfRegistration": "16-10-2020",
      "manufacturer": "string",
      "model": "string",
      "derivative": "string",
      "capCode": "ALGU21S164SDTA",
      "CurrentMileage": 25000,
      "vatRate": 20,
      "netValue": 5000
    },
    "additionalAssets": [
      {
        "type": "MOT",
        "netValue": 250,
        "vatRate": 20,
        "description": "string"
      },
      {
        "type": "BCI_VAT",
        "netValue": 350,
        "vatRate": 5,
        "description": "string"
      }
    ]
  }
}

现有代码

public static void CallRequest(string fieldName, string enteredFieldValue)
{
    string sendProposalRequestSuccess = File.ReadAllText(sendProposalUnityJSONFile);
    dynamic jsonObj = JsonConvert.DeserializeObject(sendProposalRequestSuccess);
    jsonObj[fieldName] = enteredFieldValue;
    string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
    File.WriteAllText(sendProposalUnityJSONFile, output);
}

方案1:直接通过dynamic层级访问

利用dynamic对象的.运算符直接访问嵌套属性,数组则通过索引定位元素:

修改嵌套对象属性

public static void CallRequest(object enteredFieldValue)
{
    string json = File.ReadAllText(sendProposalUnityJSONFile);
    dynamic jsonObj = JsonConvert.DeserializeObject(json);
    
    // 修改dealer下的dealerID
    jsonObj.dealer.dealerID = 12345;
    // 修改financeDetails下的cashDeposit
    jsonObj.financeDetails.cashDeposit = 200;
    // 修改更深层的vehicleAsset.netValue
    jsonObj.financeDetails.vehicleAsset.netValue = 6000;
    
    string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
    File.WriteAllText(sendProposalUnityJSONFile, output);
}

修改数组元素

public static void CallRequest(object enteredFieldValue)
{
    string json = File.ReadAllText(sendProposalUnityJSONFile);
    dynamic jsonObj = JsonConvert.DeserializeObject(json);
    
    // 修改数组第一个元素的netValue
    jsonObj.financeDetails.additionalAssets[0].netValue = 300;
    // 替换数组第二个元素
    jsonObj.financeDetails.additionalAssets[1] = new
    {
        type = "BCI_VAT",
        netValue = 400,
        vatRate = 5,
        description = "Updated Asset"
    };
    
    string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
    File.WriteAllText(sendProposalUnityJSONFile, output);
}

方案2:支持路径字符串的通用修改方法

如果需要通过传入路径字符串(如"dealer.dealerID"、"financeDetails.additionalAssets[0].netValue")动态修改,可实现路径解析逻辑:

public static void CallRequest(string fieldPath, object enteredFieldValue)
{
    string json = File.ReadAllText(sendProposalUnityJSONFile);
    dynamic jsonObj = JsonConvert.DeserializeObject(json);
    
    // 拆分路径段,处理普通节点和数组索引
    var segments = new List<string>();
    int pos = 0;
    while (pos < fieldPath.Length)
    {
        if (fieldPath[pos] == '[')
        {
            // 提取数组索引段(如[0])
            int closeBracket = fieldPath.IndexOf(']', pos);
            segments.Add(fieldPath.Substring(pos, closeBracket - pos + 1));
            pos = closeBracket + 1;
            // 跳过后续的.(如果存在)
            if (pos < fieldPath.Length && fieldPath[pos] == '.') pos++;
        }
        else
        {
            // 提取普通节点段
            int nextDot = fieldPath.IndexOf('.', pos);
            nextDot = nextDot == -1 ? fieldPath.Length : nextDot;
            segments.Add(fieldPath.Substring(pos, nextDot - pos));
            pos = nextDot + 1;
        }
    }
    
    // 遍历路径段,定位到目标父节点
    dynamic current = jsonObj;
    for (int i = 0; i < segments.Count - 1; i++)
    {
        string seg = segments[i];
        if (seg.StartsWith('[') && seg.EndsWith(']'))
        {
            // 处理数组索引
            int index = int.Parse(seg.Substring(1, seg.Length - 2));
            current = current[index];
        }
        else
        {
            // 处理普通对象属性
            current = current[seg];
        }
    }
    
    // 设置目标值
    string lastSeg = segments[^1];
    if (lastSeg.StartsWith('[') && lastSeg.EndsWith(']'))
    {
        int index = int.Parse(lastSeg.Substring(1, lastSeg.Length - 2));
        current[index] = enteredFieldValue;
    }
    else
    {
        current[lastSeg] = enteredFieldValue;
    }
    
    string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
    File.WriteAllText(sendProposalUnityJSONFile, output);
}

// 调用示例
CallRequest("dealer.dealerID", 12345);
CallRequest("financeDetails.vehicleAsset.netValue", 6000);
CallRequest("financeDetails.additionalAssets[0].netValue", 300);
CallRequest("financeDetails.additionalAssets[1]", new 
{ 
    type = "BCI_VAT", 
    netValue = 400, 
    vatRate = 5, 
    description = "Updated Asset" 
});

方案3:强类型模型修改(更安全可靠)

如果JSON结构固定,建议定义对应的C#模型类,通过强类型操作避免dynamic的类型隐患:

定义模型类

public class ProposalRequest
{
    public string externalReference { get; set; }
    public string proposalType { get; set; }
    public Dealer dealer { get; set; }
    public FinanceDetails financeDetails { get; set; }
}

public class Dealer
{
    public int dealerID { get; set; }
}

public class FinanceDetails
{
    public string type { get; set; }
    public int cashDeposit { get; set; }
    public int settlement { get; set; }
    public int partExchange { get; set; }
    public int term { get; set; }
    public double apr { get; set; }
    public double loanamount { get; set; }
    public bool distanceSelling { get; set; }
    public VehicleAsset vehicleAsset { get; set; }
    public List<AdditionalAsset> additionalAssets { get; set; }
}

public class VehicleAsset
{
    public string type { get; set; }
    public string @class { get; set; } // 转义关键字class
    public string source { get; set; }
    public string purpose { get; set; }
    public string vrm { get; set; }
    public string dateOfRegistration { get; set; }
    public string manufacturer { get; set; }
    public string model { get; set; }
    public string derivative { get; set; }
    public string capCode { get; set; }
    public int CurrentMileage { get; set; }
    public int vatRate { get; set; }
    public int netValue { get; set; }
}

public class AdditionalAsset
{
    public string type { get; set; }
    public int netValue { get; set; }
    public int vatRate { get; set; }
    public string description { get; set; }
}

强类型修改代码

public static void UpdateProposal<T>(Expression<Func<ProposalRequest, T>> propertySelector, T value)
{
    string json = File.ReadAllText(sendProposalUnityJSONFile);
    ProposalRequest request = JsonConvert.DeserializeObject<ProposalRequest>(json);
    
    // 解析表达式定位目标属性
    MemberExpression memberExpr = (MemberExpression)propertySelector.Body;
    PropertyInfo targetProperty = (PropertyInfo)memberExpr.Member;
    object targetObject = request;
    
    // 遍历嵌套层级,找到属性所在的对象
    while (memberExpr.Expression is MemberExpression parentExpr)
    {
        PropertyInfo parentProperty = (PropertyInfo)parentExpr.Member;
        targetObject = parentProperty.GetValue(targetObject);
        memberExpr = parentExpr;
    }
    
    // 设置属性值
    targetProperty.SetValue(targetObject, value);
    
    string output = JsonConvert.SerializeObject(request, Formatting.Indented);
    File.WriteAllText(sendProposalUnityJSONFile, output);
}

// 调用示例
UpdateProposal(req => req.dealer.dealerID, 12345);
UpdateProposal(req => req.financeDetails.cashDeposit, 200);
UpdateProposal(req => req.financeDetails.additionalAssets[0].netValue, 300);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:55:30