DateOnly 是自 .NET 6 以来一直存在的一种新数据类型。DateOnly 数据类型允许我们存储日期(年、月、日),而无需_小时、分钟_、_秒_或时区信息。
Entity Framework 还_支持 DateOnly_ 数据类型。在 SQL Server 中,DateOnly 将_映射_到数据库上的_日期_数据类型。
date 数据类型只需要 3 个字节_的_存储,而 datetime 数据类型需要多达 8 个字节。因此,如果我们只想存储日期数据,_日期_数据类型将更有效。
public sealed class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateOnly? BirthDate { get; set; }
}
在上面的代码示例中,_Person 类_的 BirthDate 属性只需要存储日期数据,不需要其中的时间信息。
遗憾的是,在 Web API 上使用 DateOnly 数据类型时_存在序列化_问题。没有用于将 DateOnly 数据类型转换为 JSON 的标准序列化,反之亦然。但幸运的是,这个问题有一个解决方案,那就是实现_自定义_ JSON 序列化。
若要实现_自定义转换器_,我们需要创建一个_继承 JsonConverter<T> 类_的 DateOnlyJsonConverter 类:
public sealed class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
private const string Format = "yyyy-MM-dd";
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateOnly.ParseExact(reader.GetString(), Format, CultureInfo.InvariantCulture);
}
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(Format, CultureInfo.InvariantCulture));
}
}
接下来,我们需要将_此自定义转换器注册_到_Program.cs_中_的方法_中:AddJsonOptions()AddController()
builder.Services.AddControllers()
.AddJsonOptions(opt =>
{
opt.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
// other converter...
});
Swagger 文档中 DateOnly 数据类型的_默认_架构不是那么好:
{
"id": 0,
"firstName": "string",
"lastName": "string",
"birthDate": {
"year": 0,
"month": 0,
"day": 0,
"dayOfWeek": 0
}
}
为了使它变得更好,我们需要向 AddSwagerGen() 方法_添加_自定义映射:
builder.Services.AddSwaggerGen(opt =>
opt.MapType<DateOnly>(() => new OpenApiSchema
{
Type = "string",
Format = "date",
Example = new OpenApiString(DateTime.Today.ToString("yyyy-MM-dd"))
})
);
因此_,Swagger_ 文档中的 DateOnly 格式更好:
{
"id": 0,
"firstName": "string",
"lastName": "string",
"birthDate": "2024-01-11"
}
源代码获取:公众号回复消息【code:31243
】