I am trying to modify an in memory JsonNode instance. Minimal reproducible code is simply (.NET Fiddle):
string jsonString =
@"{
""Date"": ""2019-08-01T00:00:00"",
""Temperature"": 25,
""Summary"": ""Hot"",
""DatesAvailable"": [
""2019-08-01T00:00:00"",
""2019-08-02T00:00:00""
],
""TemperatureRanges"": {
""Cold"": {
""High"": 20,
""Low"": -10
},
""Hot"": {
""High"": 60,
""Low"": 20
}
}
}
";
JsonNode jDataSet = JsonNode.Parse(jsonString)!;
var dataSet = jDataSet.AsObject();
foreach (var entry in dataSet)
{
if (entry.Key == "TemperatureRanges")
{
entry.Value.AsObject().Remove("Hot");
}
else if (entry.Key == "Date")
{
dataSet.Remove(entry.Key); // boom !
}
}
Obviously this is the wrong approach (as seen with other structure here), how should I re-write the above code to handle removal of JsonNode
in my case ?
Current code trigger:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at System.Text.Json.JsonPropertyDictionary`1.GetEnumerator()+MoveNext()
at Tests.UnitTest1.Test2() in C:\Users\malat\project\tests\Tests\UnitTest1.cs:line 43
Using:
> dotnet --version
6.0.408
Fundamentally my question is identical to this one but for JsonNode.
Three options present themselves:
Call ToList()
to create a sequence to iterate over that won't be modified by calling Remove
:
foreach (var entry in dataSet.ToList())
That's somewhat inefficient of course - whether that's a problem or not for you will depend on your app.
Don't do the removal in the loop, but keep a list of keys you want to remove after iterating over dataSet
.
Don't bother keeping a list - just unconditionally call dataSet.Remove("Date")
after the loop. (In your example at least, you know the key you want to remove - and Remove
doesn't throw an exception if the key is missing anyway.)