使用 NodaTime LocalDate 调用 Web api POST (abp appservice) 无法序列化

Posted

技术标签:

【中文标题】使用 NodaTime LocalDate 调用 Web api POST (abp appservice) 无法序列化【英文标题】:Calling Web api POST (abp appservice) with a NodaTime LocalDate fails to serialize 【发布时间】:2021-10-18 10:03:56 【问题描述】:

我正在尝试使用abp.io 编写一个Web api 并实现NodaTime。 每当我尝试调用 POST 操作时,我都会得到

验证期间检测到以下错误。\r\n - 无法将 JSON 值转换为 NodaTime.LocalDate。

我已经在模块中正确配置了 NodaTime,我还在常规的 .net 5 web api 中对其进行了测试,并且工作正常。

这是我的配置:

private void ConfigureNodaSerialization()
    
        Configure<JsonSerializer>(options =>
        
            options.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
            //options.Converters.Add(NodaConverters.LocalDateConverter);
        );
    

我正在使用 NodaTime.Serialization.JsonNet

我也试过 NodaTime.Serialization.SystemTextJson 无济于事,同样的结果。

..这里是应用服务:

[AllowAnonymous]
public class NodaTestAppService : TestAppService, INodaTestAppService

    public Task PostNodaTest([FromBody]NodaTestDto dto)
    
        return Task.CompletedTask;
    

    public Task GetNodaTest(NodaTestDto dto)
    
        return Task.CompletedTask;
    

GET 工作正常,问题在于 POST。

这是 dto:

public class NodaTestDto

    public LocalDate Date  get; set; 
    public string NodaString  get; set; 

我怀疑问题出在 Abp 序列化上。

我在 github here 上有我的测试解决方案。

这是我尝试请求的卷曲:

curl -X 'POST' 'https://localhost:44333/api/app/noda-test/noda-test' -H '接受:/' -H '内容类型:应用程序/json' -H 'RequestVerificationToken: CfDJ8N-JsQhR2mhIqO-RkZtn61KwWgiFfjD60I0EMa07QTooLF9dC8LPmQEDtTws8MpTUtl8b0gtuE-NAiBAXxHEu8IyU8-4w0MfVB4IeZTRsWwXIgzc7pQYReLYnV1IVp0icR5AQ- -d' “日期”:“1991-08-28”, “nodaString”:“字符串” '

【问题讨论】:

【参考方案1】:

ABP 的source code 表明Newtonsoft.Json 是在MvcNewtonsoftJsonOptions(而不是JsonSerializer)上配置的:

services.Configure<MvcNewtonsoftJsonOptions>(jsonOptions =>  
    // configuration settings go here.

您可能希望使用NodaTime.Serialization.JsonNet 以类似的方式进行操作。

private void ConfigureNodaSerialization(ServiceConfigurationContext context)

    context.Services.Configure<MvcNewtonsoftJsonOptions>(options =>
    
        options.SerializerSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    );

我使用下面的包参考。

<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.0.0" />

更新

documentation 声明 ABP 正在使用混合方法,使用 System.Text.Json 并针对不支持的类型回退到 Newtonsoft.Json;它展示了如何在特定课程或任何地方继续使用Newtonsoft.Json

我采取的方法是只将Newtonsoft.Json 用于NodaTestDto 类,以及上面显示的NodaTime 配置。

TestHttpApiHostModule 中的 ConfigureNodaSerialization 方法应如下所示。

private void ConfigureNodaSerialization()

    // Use Newtonsoft.Json for NodaTestDto.
    Configure<AbpSystemTextJsonSerializerOptions>(options =>
    
        options.UnsupportedTypes.AddIfNotContains(typeof(NodaTestDto));
    );
    
    // Configure Nodatime (de)serialization.
    Configure<MvcNewtonsoftJsonOptions>(jsonOptions =>
    
        jsonOptions.SerializerSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    );

现在,当使用Swagger UI 发布 "date": "1991-08-28", "nodaString": "string" json 有效负载时,您的NodaTestAppService 会收到一个有效的LocalDate 实例:

【讨论】:

遗憾的是,它给了我无法序列化的相同结果。 @Vima91 更新了答案 非常感谢!我已经被困了两个多星期了!

以上是关于使用 NodaTime LocalDate 调用 Web api POST (abp appservice) 无法序列化的主要内容,如果未能解决你的问题,请参考以下文章

如何在 WCF 中将 Noda Time(或任何第三方类型)对象作为参数传递?

如何使用 System.CommandLine 绑定 NodaTime.Duration?

如何准确获取“年”中两个 DateTime 对象之间的差异 [已关闭,使用 NodaTime] [重复]

MassTransit 与 Kafka 和 NodaTime

实体框架核心 NodaTime 总和持续时间

Rest API 调用返回带有 LocalDate 的错误