C# 如何更新JSON字符串中的属性值?

C# 如何更新JSON字符串中的属性值?,c#,json,C#,Json,以下是我的JSON: [ { "name": "Node-1", "flag": true, "myObj": { region: { info: { name: null, infoFlag: false, } } }, "nodes": [ { "name": "Node-1-1", "flag": true

以下是我的JSON:

[
  {
    "name": "Node-1",
    "flag": true,
    "myObj": {
      region: {
        info: {
          name: null,
          infoFlag: false,

        }
      }
    },
    "nodes": [
      {
        "name": "Node-1-1",
        "flag": true,
        "myObj": {
          region: {
            info: {
              name: "abc",
              infoFlag: false,

            }
          }
        },
        "nodes": [
          {
            "name": "Node-1-1-1",
            "flag": true,
            "myObj": {
              region: {
                info: {
                  name: "xyz",
                  infoFlag: false,

                }
              }
            },
            "nodes": [

            ]
          }
        ]
      }
    ]
  }
]
我想用以下规则更新上述JSON字符串的两个属性:

标志:我想盲目地将此属性更新为
false

infoFlag:如果
info
name
属性为
null
则我想将
infoFlag
更新为
true
否则
false
如果
不为null

因此,在使用这些规则更新JSON之后,我希望将该JSON作为字符串

注意:我不想反序列化然后根据以上两条规则更新属性,因为我的JSON有很多属性,我不想为它们创建类,所以我正在寻找一些可以在不反序列化类的情况下工作的属性

这就是我试图做到的:

string json = "MyJson";
var temp =  JArray.Parse(json);
temp.Descendants()
    .OfType<JProperty>()
json = temp.ToString();

如果我理解了您的需求,那么这段代码非常冗长,不那么优雅,但可以工作:

    JArray temp =  JArray.Parse(json);

    foreach (JToken tk in temp.Descendants())
    {
        if (tk.Type == JTokenType.Property)
        {
            JProperty p = tk as JProperty;

            if (p.Name == "flag")
            {
                if ((bool)p.Value.ToObject(typeof(bool)) == true)
                    p.Value = false;
            }

            if ((p.Name == "info") && p.HasValues)
            {
                bool flag = false;

                foreach (JToken tkk in p.Descendants())
                {
                    if (tkk.Type == JTokenType.Property)
                    {
                        JProperty pp = tkk as JProperty;

                        if ((pp.Name == "name") && (pp.Value.Type == JTokenType.Null))
                        {
                            flag = true;
                        }

                        if ((pp.Name == "infoFlag"))
                        {
                            pp.Value = (flag == true) ? true : false;
                        }
                    }
                }
            }
        }
    }

    json = temp.ToString();
这是结果输出:

[
  {
    "name": "Node-1",
    "flag": false,
    "myObj": {
      "region": {
        "info": {
          "name": null,
          "infoFlag": true
        }
      }
    },
    "nodes": [
      {
        "name": "Node-1-1",
        "flag": false,
        "myObj": {
          "region": {
            "info": {
              "name": "abc",
              "infoFlag": false
            }
          }
        },
        "nodes": [
          {
            "name": "Node-1-1-1",
            "flag": false,
            "myObj": {
              "region": {
                "info": {
                  "name": "xyz",
                  "infoFlag": false
                }
              }
            },
            "nodes": []
          }
        ]
      }
    ]
  }
]
允许您将表示JSON内容的内部对象视为
动态
,这使得所讨论的任务不比使用常规类型的对象困难

唯一一种棘手的问题是递归对象结构(节点数组),但这不是JSON或
动态
特定的问题,可以通过多种方式解决-明显的递归方法或使用我更喜欢的树展平枚举(我的答案中的
扩展
方法)

话虽如此,解决方案可能是这样的:

var array = JArray.Parse(json);
var nodes = array.Cast<dynamic>().Expand(x => x.nodes);
foreach (var node in nodes)
{
    node.flag = true;
    var info = node.myObj.region.info;
    info.infoFlag = (info.name == null);
}
var newJson = array.ToString();
var-array=JArray.Parse(json); var nodes=array.Cast().Expand(x=>x.nodes); foreach(节点中的var节点) { node.flag=true; var info=node.myObj.region.info; info.infoFlag=(info.name==null); } var newJson=array.ToString();
您可以复制的文件。alertnative根本不进行反序列化,但是您必须编写一个非常智能的解析器。@GolezTrol问这个问题的主要目的是如何定位和更新属性值,而不必在类中进行反序列化。我非常清楚如何将json字符串反序列化到动态对象:),那么您为什么说“有很多属性,我不想为它们创建类“。使用动态对象,您可以完全做到这一点。JArray.Parse也可以反序列化。如果您想在不进行反序列化的情况下替换属性,则必须坚持使用
String.replace
或一些正则表达式魔术,但我肯定你不想走这条路。@GolezTrol反序列化到任何动态对象都可以,但我只是说我不想反序列化到任何类,因为我不想创建类来处理这种反序列化。此外,我正在努力的部分是在反序列化到动态对象后操作这些属性反对。这真是太美了:)这很有效。非常感谢你,请继续像往常一样给出天才和精彩的答案:)感谢你为帮助我所做的努力。感谢:)
var array = JArray.Parse(json);
var nodes = array.Cast<dynamic>().Expand(x => x.nodes);
foreach (var node in nodes)
{
    node.flag = true;
    var info = node.myObj.region.info;
    info.infoFlag = (info.name == null);
}
var newJson = array.ToString();