I have a strange error with Dapper (2.0.30) on new DotNet Core 3.0.
I am trying to load data from database with this command:
await connection.QueryAsync(command)).AsList()
And I want to return result as json
return this.Ok(Database.Load("SELECT * FROM table_name;"));
But I am getting this strange error:
System.InvalidCastException: Unable to cast object of type '<GetEnumerator>d__9' to type 'System.Collections.IDictionaryEnumerator'.
at System.Text.Json.JsonSerializer.HandleDictionary(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I tried exact same code on DotNet 2.0 and it worked. I guess that it has something to do with new build in json serialize, that is not compatible with dapper or something?
I looked up on internet but I could not find much (nothing actually) about this. Just this quote from this website
This looks like a bug in how we deal with types that implement IDictionary where we expect such types to return an enumerator that implements IDictionaryEnumerator (and types like DapperRow don't implement that interface).
System.Text.Json.Serialization.Tests.ValueTests.DapperTest [FAIL]
System.InvalidCastException : Unable to cast object of type '<GetEnumerator>d__9' to type 'System.Collections.IDictionaryEnumerator'.
Stack Trace:
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.HandleDictionary.cs(64,0): at System.Text.Json.JsonSerializer.HandleDictionary(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.cs(40,0): at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(131,0): at System.Text.Json.JsonSerializer.WriteCore(Utf8JsonWriter writer, Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(107,0): at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(86,0): at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.String.cs(21,0): at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\tests\Serialization\Value.WriteTests.cs(47,0): at System.Text.Json.Serialization.Tests.ValueTests.DapperTest()
Therefore, we are failing at this cast, since the enumerator that DapperRow returns is IEnumerator> and not IDictionaryEnumerator: https://github.com/dotnet/corefx/blob/b832f6ccdebd18469e4b6d03c1c9b2c9c6c14374/src/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs#L64
Does anyone knows how to make it work? Thanks
Update:
I kinda fix it.
First I added libary from nudget Microsoft.AspNetCore.Mvc.NewtonsoftJson. And added Newtonsoft as default json middleware.
services.AddMvc()
.AddNewtonsoftJson();
And
services.AddControllers()
.AddNewtonsoftJson();
But I still dont know why it did not run out of box, as it was on previous version of DotNet core.