使用 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] [重复]