source

"Newtonsoft에서 항목을 추가하거나 제거할 수 없습니다.Json.Linq.JProperty"를 참조해 주세요.

bestscript 2023. 2. 12. 18:06

"Newtonsoft에서 항목을 추가하거나 제거할 수 없습니다.Json.Linq.JProperty"를 참조해 주세요.

따라서 json 객체를 JObject로 읽고 필드를 삭제한 다음 Json을 사용하여 타깃 객체에 다시 역직렬화함으로써 역직렬화를 제어하려고 합니다.Net. 문제는 필드를 삭제하려고 할 때마다 다음과 같은 오류가 발생한다는 것입니다.

처리되지 않은 예외 유형 'Newtonsoft'입니다.Json.JsonException'은 Newtonsoft에서 발생했습니다.Json.dll

추가 정보: 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는 입니다.List<MyObject>그리고 당신의MyObjectclass는 다음과 같습니다.

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클래스에는 다음 항목이 포함되어 있지 않습니다._idJSON에서 삭제하려고 후프를 건너뛰지 않아도 됩니다.

이유 설명Remove()작동하지 않았다

JToken.Remove()를 삭제합니다.JToken그 부모로부터.를 삭제하는 것은 합법입니다.JProperty그 부모로부터JObject, 또는 아이를 제거합니다.JToken에서JArray단, 이 값은 에서 삭제할 수 없습니다.JProperty.aJProperty에는 항상 정확히 하나의 값이 있어야 합니다.

당신이 요청할 때token["_id"]가치를 되찾을 수 있습니다.JProperty불렀다_id,가 아니라JProperty그 자체입니다.따라서 전화를 걸려고 하면 오류가 발생합니다.Remove()그 가치로.지금처럼 작동시키려면Parent다음과 같습니다.

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

"이름을 가진 부동산 찾기"라고 적혀 있습니다._id그 가치를 제게 주세요.존재하는 경우 해당 값의 부모(속성)를 가져와 부모(포함)에서 삭제합니다.JObject)."

보다 간단한 방법은 다음과 같이 하는 것입니다.Property()메서드를 사용하여 직접 자산에 액세스합니다.단, 이 메서드는 다음에서만 사용할 수 있습니다.JObject,것은 아니다.JToken따라서 선언을 변경해야 합니다.inner에 대해서JObject또는 캐스팅:

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

마지막으로 코멘트에 기재된 바와 같이 C#6 이후를 사용하는 경우 null-conditional 연산자를 사용하여 코드를 약간 단축할 수 있습니다.

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

Brian의 훌륭한 답변에 근거해, 다음과 같이 간단하게 할 수 있습니다.

var inner_id = inner["_id"] as JProperty;
if (inner_id != null)
  inner_id.Remove();

언급URL : https://stackoverflow.com/questions/21898727/getting-the-error-cannot-add-or-remove-items-from-newtonsoft-json-linq-jpropert