C#读取并更新文件JSON数组时触发只读错误,如何解决?
解决JSON数组属性更新时的只读错误问题
嘿,我来帮你搞定这个JSON更新的麻烦!你碰到的「Property or indexer cannot be assigned to -- it is read only」错误,核心原因是遍历JObject的方式不对,导致拿到的是只读的键值对。咱们先拆解问题,再给你修正后的代码。
问题出在哪?
你这段代码里有两个小问题:
- 把
jsonArray[0]转成字符串再解析成JObject完全没必要——jsonArray[0]本身就是JObject类型,直接强制转换就行。 - 直接遍历
JObject得到的是KeyValuePair<string, JToken>,它的Value是只读属性,自然没法直接赋值。
正确的实现方式
如果要更新对象里的所有属性值,或者指定属性,咱们可以这么写:
方式1:更新所有属性(包括嵌套的elements)
var referenceFile = @"TestData\report.json"; var json1 = File.ReadAllText(referenceFile); JArray jsonArray = JArray.Parse(json1); // 直接获取数组中的第一个JObject,无需多余的字符串解析 JObject targetObj = (JObject)jsonArray[0]; // 遍历JObject的属性集合(用Properties()方法拿到可修改的JProperty) foreach (var prop in targetObj.Properties()) { // JProperty的Value是可写的,直接赋值即可 prop.Value = "test"; } // 如果还要更新嵌套的elements数组里的对象 JArray elements = (JArray)targetObj["elements"]; foreach (var elem in elements) { JObject elemObj = (JObject)elem; foreach (var elemProp in elemObj.Properties()) { elemProp.Value = "updated nested test"; } } // 最后把修改后的JSON写回文件(保留格式化) File.WriteAllText(referenceFile, jsonArray.ToString(Newtonsoft.Json.Formatting.Indented));
方式2:只更新指定属性(更常用)
如果不需要改所有属性,只想更新比如description或者name,可以直接定位属性修改,更高效:
var referenceFile = @"TestData\report.json"; var json1 = File.ReadAllText(referenceFile); JArray jsonArray = JArray.Parse(json1); JObject targetObj = (JObject)jsonArray[0]; // 修改顶层的description targetObj["description"] = "这是更新后的描述"; // 修改name属性 targetObj["name"] = "更新后的Feature名称"; // 修改嵌套elements里的第一个对象的description JArray elements = (JArray)targetObj["elements"]; ((JObject)elements[0])["description"] = "嵌套元素的更新描述"; // 写回文件,保留格式化 File.WriteAllText(referenceFile, jsonArray.ToString(Newtonsoft.Json.Formatting.Indented));
关键知识点
- 不要把
JToken(比如JObject、JArray)转成字符串再重新解析,直接用强制类型转换就行,既高效又避免出错。 - 遍历
JObject的可修改属性,一定要用Properties()方法,它返回的JProperty对象的Value是可写的;直接遍历JObject得到的是只读的KeyValuePair,这就是你报错的原因。 - 修改完成后记得把整个
JArray写回文件,这样所有修改才会生效。
内容的提问来源于stack exchange,提问作者spartycurse
相关产品推荐
相关产品推荐

