runtime: JsonSerializer throwing "System.NotSupportedException : Collection was of a fixed size" for some array/collection parsing
Before adding
SimpleTestClass MySampleTestClass { get; set; } property to the SimpleTestStruct struct and json test was running successfully, after adding object type JsonSerializer cannot parse it anymoreUpdate: The original test failure is fixed with recent update, but the below case is still failing so updated the test case
Exception: System.NotSupportedException : Collection was of a fixed size.
[Fact]
public void TestMethod1()
{
var state = new AppState();
string serialized = "{\"Values\":[1,2,3]}";
object deserializedState = System.Text.Json.Serialization.JsonSerializer.Parse(serialized, typeof(AppState));
}
public class AppState
{
public int[] Values { get; set; }
public AppState()
{
Values = Array.Empty<int>();
}
}
System.NotSupportedException : Collection was of a fixed size.
Stack Trace:
/_/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs(482,0): at System.SZArrayHelper.Add[T](T value)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.HandleArray.cs(264,0):
at System.Text.Json.JsonSerializer.ApplyValueToEnumerable[TProperty](TProperty& value, ReadStack& state, Utf8JsonReader& reader)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonPropertyInfoNotNullable.cs(67,0) :
at System.Text.Json.JsonPropertyInfoNotNullable`3.ReadEnumerable(JsonTokenType tokenType, ReadStack& state, Utf8JsonReader& reader)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonPropertyInfoNotNullable.cs(25,0) :
at System.Text.Json.JsonPropertyInfoNotNullable`3.Read(JsonTokenType tokenType, ReadStack& state, Utf8JsonReader& reader)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.HandleValue.cs(28,0):
at System.Text.Json.JsonSerializer.HandleValue(JsonTokenType tokenType, JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& state)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.cs(48,0):
at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.Helpers.cs(22,0) :
at System.Text.Json.JsonSerializer.ReadCore(Type returnType, JsonSerializerOptions options, Utf8JsonReader& reader)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.String.cs(74,0):
at System.Text.Json.JsonSerializer.ParseCore(String json, Type returnType, JsonSerializerOptions options)
D:\dotnet\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.String.cs(31,0):
at System.Text.Json.JsonSerializer.Parse[TValue](String json, JsonSerializerOptions options)
D:\dotnet\corefx\src\System.Text.Json\tests\Serialization\Object.ReadTests.cs(312,0):
at System.Text.Json.Serialization.Tests.ObjectTests.ReadStructObjectValueTest()
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 28 (25 by maintainers)
Tested using three popular serializers and they behave near the same. All of them replace a collection if it’s readonly (
ArrayandCollectionBackedByArraycases), but if a collection is mutable (i.e.CollectionBackedByList) then only Newtonsoft appends new values. Utf8Json and Jil still replace the original object.Probably we should align the behavior with Jil and Utf8Json because it’s common for all collections and more intuitive when there is a public setter (it says that you’re allowed to replace collection and should do it).
A more simple test-case. Note: The problem is resolved if you mark the property setter private.
Sorry for not answering early, was very busy. I will take a look at it tomorrow and fix ASAP.
I ran into this issue even with public setter, and finally figured out the root cause:
JsonSerializerOptions.IgnoreNullValuesistrue. Changing it to defaultfalseresolved my issue.@ahsonkhan Because there are cases when you have your own collection which can’t be instantiated by a third party. Mostly it’s because a collection needs to know about it’s owner. So the best strategy here is:
I agree that Newtonsoft is the odd one out. Replacing the original object makes more sense to do by default.
In the future if you want to extend behavior to support appending then you can add it as a setting.
@wcontayon i am not that familiar with the code base, so not sure why that llist has fixed size or if it is really need to be fixed size. But creating new list to add a new value is most likely not an option.
@ahsonkhan yes you are right, never mind
That is expected. The json string you passed in is invalid JSON. A JSON object cannot contain just a string value. It must have
property name: valuepairs.