原来,有两种解决方案:
我选择了TypeConverter,一切正常!自从 .Net 团队 are not planning to add full support for DateOnly/TimeOnly in .Net 6 以来,我决定创建一个 NuGet 来这样做:
https://www.nuget.org/packages/DateOnlyTimeOnly.AspNet (source code)
将其添加到项目并按照描述配置Program.cs 后,问题描述中描述的操作的 Swagger 将如下所示:
它是如何工作的
首先,您需要声明从string 到DateOnly 的类型转换器(以及从string 到TimeOnly 的一个):
using System.ComponentModel;
using System.Globalization;
namespace DateOnlyTimeOnly.AspNet.Converters;
public class DateOnlyTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string str)
{
return DateOnly.Parse(str);
}
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
{
if (destinationType == typeof(string) && value is DateOnly date)
{
return date.ToString("O");
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
(DateOnly的一个相同,但DateOnly替换为TimeOnly)
比TypeConverterAttribute 需要添加到DateOnly 和TimeOnly。可以这样做:
TypeDescriptor.AddAttributes(typeof(DateOnly), new TypeConverterAttribute(typeof(DateOnlyTypeConverter)));
TypeDescriptor.AddAttributes(typeof(TimeOnly), new TypeConverterAttribute(typeof(TimeOnlyTypeConverter)));
为了更简洁,可以将这段代码包装在扩展方法中:
using DateOnlyTimeOnly.AspNet.Converters;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
namespace Microsoft.Extensions.DependencyInjection;
public static class MvcOptionsExtensions
{
public static MvcOptions UseDateOnlyTimeOnlyStringConverters(this MvcOptions options)
{
TypeDescriptor.AddAttributes(typeof(DateOnly), new TypeConverterAttribute(typeof(DateOnlyTypeConverter)));
TypeDescriptor.AddAttributes(typeof(TimeOnly), new TypeConverterAttribute(typeof(TimeOnlyTypeConverter)));
return options;
}
}
用法:
builder.Services.AddControllers(options => options.UseDateOnlyTimeOnlyStringConverters())