Error when serializing IAsyncEnumerable in .NET 6
I've had a piece of code that serializes an IAsyncEnumerable since this type was introduced in .NET Core 3.1 and it's been working great together with SpanJson.
Recently, I upgraded to the newly released .NET 6 and after testing my application I got a long stack of errors at the location that serializes this type.
Would you mind checking what's causing the issue?
ArgumentException: Type 'System.Runtime.InteropServices.StructLayoutAttribute' does not have a default constructor (Parameter 'type')
System.Linq.Expressions.Expression.New(Type type)
SpanJson.Formatters.ComplexFormatter.BuildDeserializeDelegate<T, TSymbol, TResolver>()
SpanJson.Formatters.ComplexClassFormatter<T, TSymbol, TResolver>..cctor()
System.RuntimeFieldHandle.GetValue(RtFieldInfo field, object instance, RuntimeType fieldType, RuntimeType declaringType, ref bool domainInitialized)
System.Reflection.RtFieldInfo.GetValue(object obj)
SpanJson.Resolvers.ResolverBase.GetDefaultOrCreate(Type type)
SpanJson.Resolvers.ResolverBase<TSymbol, TResolver>.BuildFormatter(Type type)
SpanJson.Resolvers.ResolverBase<TSymbol, TResolver>.<GetFormatter>b__3_0(Type x)
System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>.GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
SpanJson.Resolvers.ResolverBase<TSymbol, TResolver>.GetFormatter(Type type)
SpanJson.Resolvers.ResolverBase<TSymbol, TResolver>.GetFormatter(JsonMemberInfo memberInfo, Type overrideMemberType)
SpanJson.Formatters.ComplexFormatter.BuildSerializeDelegate<T, TSymbol, TResolver>()
SpanJson.Formatters.ComplexClassFormatter<T, TSymbol, TResolver>..cctor()
(The chain of errors is much longer than this but looks very similar to above)
Honestly I'm surprised that IAsyncEnumerable works at all.
Oh, why is that?
A clarification, this was actually the return type of an action in ASP.NET Core. It used to serialize it as a regular IEnumerable<>, but doesn't work in .NET 6.
IAsnycEnumerable only works properly if you have a full async pipeline. I guess that in 5.0 it was actually sync or fully synchronously buffered and in 6.0 it's not anymore.
Okay, I see then. I converted it to a Task<ActionResult<IEnumerable<>>> to make it work. The error occurs when SpanJson is scanning and reflecting the controller actions to determine how to serialize each respective response.
It would be quite useful if you could provide a repro for your problem, this problem is likely dependent on one of the concrete types.
Just create an ASP.NET Core project with a controller containing an action with the return type IAsyncEnumerable<> targeting .NET 6, and you should hit the error as soon as you launch the app.
Okay, you still return IAsnycEnumerable, I was confused as you wrote about Ienumerable in between. As I previously said, this can't work properly.