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

C#基于字符串路径修改动态JSON属性及GetProperty空引用报错解决

业务需求

收到的根级JSON payload包含两个属性:

  • instructions
  • base
    需要将instructions中的修改规则应用到base JSON对象上。举例来说,按照示例payload的规则,需要遍历到base属性中defaultWidget下的widgets节点,将其值完全替换为patchedValue对应的取值。

输入Payload

{
    "instructions": [
        {
            "patchedPath": "defaultWidget.widgets",
            "patchedValue": false
        }
    ],
    "base": {
        "defaultWidget": {
            "hash": "ktocle2l0u527",
            "layout": "6|6",
            "managerId": "defaultWidget",
            "widgets": [
                {
                    "managerId": "defaultWidget",
                    "widgetId": "invCreateWid7",
                    "type": "standard",
                    "manifestPath": "nexxe.standard-section@0.0.0-next.11",
                    "defaultInputManifestPath": "nexxe.input@0.0.1-alpha.49",
                    "title": "scannedInvoice",
                    "children": [
                        {
                            "name": "tom"
                        }
                    ],
                    "hash": "ktocle2lrgps9",
                    "directives": ""
                }
            ]
        }
    }
}

预期输出结果

{    
    "base": {
        "defaultWidget": {
            "hash": "ktocle2l0u527",
            "layout": "6|6",
            "managerId": "defaultWidget",
            "widgets": false
        }
    }
}

现有问题

当前代码运行时触发空引用报错:

System.NullReferenceException: 'Object reference not set to an instance of an object.'
System.Type.GetProperty(...) returned null.

报错原因是JsonConvert.DeserializeObject不带泛型时返回的是object类型,实际底层是Newtonsoft.Json的JObject实例,并非自定义类,无法通过反射GetProperty获取JSON属性。

当前编写的错误代码:

var stringPayload = "{    \"instructions\": [        {            \"patchedPath\": \"defaultWidget.widgets\",            \"patchedValue\": false,        }    ],    \"base\": {        \"defaultWidget\": {            \"hash\": \"ktocle2l0u527\",            \"layout\": \"6|6\",            \"managerId\": \"defaultWidget\",            \"widgets\": [                {                    \"managerId\": \"defaultWidget\",                    \"widgetId\": \"invCreateWid7\",                    \"type\": \"standard\",                    \"manifestPath\": \"nexxe.standard-section@0.0.0-next.11\",                    \"defaultInputManifestPath\": \"nexxe.input@0.0.1-alpha.49\",                    \"title\": \"scannedInvoice\",                    \"children\": [                        {                            \"name\": \"tom\"                        }                    ],                    \"hash\": \"ktocle2lrgps9\",                    \"directives\": \"\"                }            ]        }    }}";
var parsedPayload = JsonConvert.DeserializeObject(stringPayload);
var baseJ = parsedPayload.GetType().GetProperty("instructions").GetValue(parsedPayload, null);
string jsonString = JsonConvert.SerializeObject(parsedPayload);

解决方案

直接使用Newtonsoft.Json的JObject原生API处理JSON节点,完整可运行代码如下:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class Program
{
    public static void Main()
    {
        var stringPayload = "{    \"instructions\": [        {            \"patchedPath\": \"defaultWidget.widgets\",            \"patchedValue\": false        }    ],    \"base\": {        \"defaultWidget\": {            \"hash\": \"ktocle2l0u527\",            \"layout\": \"6|6\",            \"managerId\": \"defaultWidget\",            \"widgets\": [                {                    \"managerId\": \"defaultWidget\",                    \"widgetId\": \"invCreateWid7\",                    \"type\": \"standard\",                    \"manifestPath\": \"nexxe.standard-section@0.0.0-next.11\",                    \"defaultInputManifestPath\": \"nexxe.input@0.0.1-alpha.49\",                    \"title\": \"scannedInvoice\",                    \"children\": [                        {                            \"name\": \"tom\"                        }                    ],                    \"hash\": \"ktocle2lrgps9\",                    \"directives\": \"\"                }            ]        }    }}";

        // 反序列化为JObject类型
        JObject parsedPayload = JsonConvert.DeserializeObject<JObject>(stringPayload);
        JArray instructions = parsedPayload["instructions"] as JArray;
        JObject baseNode = parsedPayload["base"] as JObject;

        // 遍历所有修改规则
        foreach (JObject instruction in instructions)
        {
            string patchedPath = instruction["patchedPath"].ToString();
            JToken patchedValue = instruction["patchedValue"];
            string[] pathSegments = patchedPath.Split('.');
            
            JToken currentNode = baseNode;
            // 逐层定位到目标节点的父节点
            for (int i = 0; i < pathSegments.Length - 1; i++)
            {
                currentNode = currentNode[pathSegments[i]];
            }
            // 赋值修改目标属性
            (currentNode as JObject)[pathSegments[^1]] = patchedValue;
        }

        // 构造输出结果
        var output = new { @base = baseNode };
        string resultJson = JsonConvert.SerializeObject(output, Formatting.Indented);
        System.Console.WriteLine(resultJson);
    }
}

该方案支持任意层级的patchedPath修改,直接调用JSON库原生API避免反射报错,运行后输出结果和预期完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:39:03