繁体   English   中英

Dot Net Core 3.0 上的 Dapper 数据序列化问题

[英]Dapper data serialization problem on Dot Net Core 3.0

我在新的 DotNet Core 3.0 上使用 Dapper (2.0.30) 有一个奇怪的错误。

我正在尝试使用以下命令从数据库加载数据:

await connection.QueryAsync(command)).AsList()

我想将结果返回为 json

return this.Ok(Database.Load("SELECT * FROM table_name;"));

但我收到了这个奇怪的错误:

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)

我在 DotNet 2.0 上尝试了完全相同的代码,并且成功了。 我想这与 json 序列化中的新版本有关,与 dapper 或其他什么不兼容?

我在网上查了一下,但我找不到太多(实际上什么都没有)。 只是这个 网站的报价

这看起来像是我们如何处理实现 IDictionary 的类型的一个错误,我们希望这些类型返回一个实现 IDictionaryEnumerator 的枚举器(并且像 DapperRow 这样的类型不实现该接口)。

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()

因此,我们在这个演员阵容中失败了,因为 DapperRow 返回的枚举数是 IEnumerator> 而不是 IDictionaryEnumerator: https://github.com/dotnet/corefx/blob/b832f6ccdebd18469e4b6d03c1c9b2c9c6c14374/System/rc/System。文本/Json/序列化/JsonSerializer.Write.HandleDictionary.cs#L64

有谁知道如何使它工作? 谢谢

更新:

我有点修复它。

首先,我从轻推Microsoft.AspNetCore.Mvc.NewtonsoftJson 添加了库。 并添加 Newtonsoft 作为默认的 json 中间件。

services.AddMvc()
    .AddNewtonsoftJson();

services.AddControllers()
    .AddNewtonsoftJson();

但我仍然不知道为什么它没有开箱即用,因为它是在以前版本的 DotNet 核心上。

正如您可以在以下文档中阅读的那样,该文档描述了如何从 Asp.net 内核 2.2 迁移到版本 3:

ASP.NET 核心的默认 JSON 序列化程序现在是 System.Text.Json,这是 Z303CB.09EDB90872 中的新功能。 尽可能考虑使用 System.Text.Json。 它是高性能的,不需要额外的库依赖。 但是,由于 System.Text.Json 是新的,它目前可能缺少您的应用所需的功能

可能新的序列化器还不支持这个功能

https://docs.microsoft.com/en-US/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio

在 .NET 3 中,新的System.Text.Json序列化器仅支持以字符串为键的字典。 如果您想要任何其他类型的字典,您要么需要编写自定义反序列化器,要么现在继续使用 Newtonsoft JSON。

这是在 .NET 5 的版本中修复的: https://github.com/dotnet/runtime/pull/38056

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM