Skip to content

Using Queue, Queue<T>, Stack, and ConcurrentStack<T> as properties in classes deserialized by System.Text.Json does not work when trimmed #53205

@eerhardt

Description

@eerhardt

Publish and run the following application with -p:PublishTrimmed=true

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text.Json;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var json = @"{""Name"":""Test"",""Sizes"":[0, 256, 256]}";

            var s = (Shape)JsonSerializer.Deserialize(json, typeof(Shape));
            Console.WriteLine(s.Sizes.Dequeue());
            Console.WriteLine(s.Sizes.Dequeue());
            Console.WriteLine(s.Sizes.Dequeue());
        }
    }

    public class Shape
    {
        public string Name { get; set; }

        //public ConcurrentStack<int> Sizes { get; set; }
        public Queue<int> Sizes { get; set; }
    }
}
  1. dotnet publish -r win-x64 -p:PublishTrimmed=true
  2. bin\Debug\net6.0\win-x64\publish\HelloWorld.exe

Expected results

The application should run, it does when I use List<T> for the property.

Actual results

Unhandled exception. System.NotSupportedException: The type 'System.Collections.Generic.Queue`1[System.Int32]' is not supported. Path: $.Sizes | LineNumber: 0 | BytePositionInLine: 24.
 ---> System.NotSupportedException: The type 'System.Collections.Generic.Queue`1[System.Int32]' is not supported.
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(Type ) in System.Text.Json.dll:token 0x60000d6+0x10
   at System.Text.Json.Serialization.Converters.QueueOfTConverter`2.CreateCollection(Utf8JsonReader& , ReadStack& , JsonSerializerOptions ) in System.Text.Json.dll:token 0x600070c+0x12
   at System.Text.Json.Serialization.Converters.IEnumerableDefaultConverter`2.OnTryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , TCollection& ) in System.Text.Json.dll:token 0x60006d9+0x32
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , T& ) in System.Text.Json.dll:token 0x6000582+0x197
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object , ReadStack& , Utf8JsonReader& ) in System.Text.Json.dll:token 0x600061c+0xdb
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , T& ) in System.Text.Json.dll:token 0x6000738+0x8f
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , T& ) in System.Text.Json.dll:token 0x6000582+0x197
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& ) in System.Text.Json.dll:token 0x600056e+0xbf
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& , Utf8JsonReader& , NotSupportedException ) in System.Text.Json.dll:token 0x60000fc+0xcb
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& ) in System.Text.Json.dll:token 0x600056e+0x1c0
   at System.Text.Json.Serialization.JsonConverter`1.ReadCoreAsObject(Utf8JsonReader& , JsonSerializerOptions , ReadStack& ) in System.Text.Json.dll:token 0x600056d+0x0
   at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter , Utf8JsonReader& , JsonSerializerOptions , ReadStack& ) in System.Text.Json.dll:token 0x60002c9+0x14
   at System.Text.Json.JsonSerializer.ReadUsingMetadata[TValue](ReadOnlySpan`1 , JsonTypeInfo , Nullable`1 ) in System.Text.Json.dll:token 0x60002ca+0x2f
   at System.Text.Json.JsonSerializer.ReadUsingMetadata[TValue](ReadOnlySpan`1 , JsonTypeInfo ) in System.Text.Json.dll:token 0x60002cd+0x59
   at System.Text.Json.JsonSerializer.ReadUsingOptions[TValue](ReadOnlySpan`1 , Type , JsonSerializerOptions ) in System.Text.Json.dll:token 0x60002cc+0x0
   at System.Text.Json.JsonSerializer.Deserialize(String , Type , JsonSerializerOptions ) in System.Text.Json.dll:token 0x60002cb+0x22
   at ConsoleApp1.Program.Main(String[] args) in C:\DotNetTest\HelloWorld\Program.cs:line 14

Notes

  1. This seems to occur for Queue, Queue<T>, Stack, and ConcurrentStack<T> types.
  2. This doesn't happen for List<T> nor Stack<T>, because I think other things are rooting their constructors.
  3. These types may be esoteric enough that we don't want to root even more code in the application with System.Text.Json serialization, and instead tell people to use the source generator if they need this behavior. The user already is getting a warning by using JsonSerializer without the source generated information.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions