当前位置: 首页 > 面试题库 >

在Json.net中收到错误“无法从Newtonsoft.Json.Linq.JProperty添加或删除项目”

长孙雅志
2023-03-14
问题内容

所以我试图通过将json对象作为JObject读取,删除一些字段,然后使用Json.Net将其反序列化为我的目标对象来控制反序列化。问题是,每当我尝试删除字段时,都会收到错误消息:

Newtonsoft.Json.dll中发生了类型为’Newtonsoft.Json.JsonException’的未处理异常

附加信息:无法从Newtonsoft.Json.Linq.JProperty添加或删除项目。

这是我的代码(已简化,但仍会导致错误):

JToken token = (JToken)JsonConvert.DeserializeObject(File.ReadAllText(fileName));

foreach (JToken inner in token["docs"])
{
    if (inner["_id"] != null)
        inner["_id"].Remove();

    MyObject read = new MyObject();
    JsonConvert.PopulateObject(inner.ToString(), read);
    Values.Add((MyObject)JsonConvert.DeserializeObject(inner.ToString(), typeof(MyObject)));
}

json是一个非常大的文件,其中docs数组包含许多元素,如下所示(为简化起见,再次简化):

{
    "docs": [
        {
            "Time": "None",
            "Level": 1,
            "_id": "10208"              
        },
        {
            "Time": "None",
            "Level": 1,
            "_id": "10209"
        }
    ]
}

或者,如果有更好的方法将JSON反序列化为特定类型,但仍然忽略其他字段,那将是一个很好的选择。


问题答案:

假设Values是a List<MyObject>,您的MyObject课程如下所示:

class MyObject
{
    public string Time { get; set; }
    public int Level { get; set; }
}

您可以将所有代码替换为以下代码,以获得所需的结果:

string json = File.ReadAllText(fileName);
Values = JToken.Parse(json)["docs"].ToObject<List<MyObject>>();

之所以可行,是因为Json.Net默认会忽略缺少的属性。由于MyObject该类不包含_id要反序列化的属性,因此您无需跳过试图将其从JSON中删除的箍。

解释为什么Remove()不起作用

JToken.Remove()``JToken从其父级中删除一个。JProperty从父母JObject中删除子女或JToken从子女中删除子女是合法的JArray。但是,您无法从中删除值JProperty。一个JProperty必须始终只有一个值。

当您要求时,token["_id"]可以获取被调用的
,而不是其本身。因此,如果尝试调用该值,将会得到一个错误。要使其按照您的方式工作,您需要使用以下代码:JProperty``_id``JProperty``Remove()``Parent

if (inner["_id"] != null)
    inner["_id"].Parent.Remove();

这样说:“查找名称为“的属性_id并给我值。如果存在,请获取该值的父级(属性),然后从其父级(包含JObject)中删除它”。

一种更直接的方法是使用该Property()方法直接访问属性。但是,此方法仅在上JObject不可用JToken,因此您需要将的声明更改inner为a
JObject或将其强制转换为:

foreach (JObject inner in token["docs"].Children<JObject>())
{
    JProperty idProp = inner.Property("_id");
    if (idProp != null)
        idProp.Remove();
    ...
}

最后,如注释中所述,如果您使用的是C#6或更高版本,则可以使用null条件运算符将代码缩短一些:

    inner.Property("_id")?.Remove();


 类似资料:
  • 问题内容: 嗨,我必须从一个JList中选择一个元素,将其从第一个元素中删除。我创建的方法仅插入一个元素,覆盖最后一个元素,并且不会从第一个JList中删除所选项目。这是代码: 第一名单 通过此方法填充: 第二个列表,我要在其中插入从第一个列表中删除的项目: 这是无效代码: 谢谢 问题答案: 问题是 您可能要添加一个元素并立即将其删除,因为添加和删除操作都在同一listModel上。 尝试

  • 我一直试图通过java代码从DynamoDB中的表中删除一项,但每次尝试都会导致相同的错误: com.amazonaws.AmazonServiceException:提供的键元素与架构不匹配(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException; 我当前的尝试非常简单,如下所示: tablename只是表名,凭证已被验证为正确,cognito

  • 我刚刚在Intellij中创建了一个简单的helloworldscala项目。我的主要课程只是打印Hello World- 我的项目结构 在项目结构设置中,我将“scala”作为我的源文件夹。我能够在我创建的应用程序运行配置中正确选择我的主类。到目前为止一切顺利。在此之后,当我尝试运行我的运行配置时,我得到了可怕的错误- 在这一点上,我已经尝试了所有我能在谷歌上找到的东西,比如使缓存失效、重新加载

  • 一个课程只有一个主题(CoursetType)和一个数字(courseNumType)。 我已经在下面粘贴了两个类的完整代码,但我认为问题是我的action listener创建了一个新对象,然后调用了一个dropClass()方法(实际上是一个list.remove())。但我不确定如何在不创建新对象的情况下传递正确的值。 这是我创建GUI和实现动作侦听器的主要方法和类: 课程类别:

  • 当试图从Eclipse Oxygen中删除一个项目时,什么也没有发生,日志中会写入一个异常。我只需在包浏览器中右键单击一个项目,然后选择“删除”选项。我用的是Eclipse Oxygen.1a (4.7.1a)。以下是完整的构建信息: 下面是一个堆栈跟踪示例: 任何想法如何解决这个问题?或任何解决方法?

  • 如何在swapCursor函数中实现回收器视图默认项添加/删除动画。notifyDataSetChanged()不会显示任何动画。