C# 如何更新JSON字符串中的属性值?
以下是我的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
[
{
"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();