gpt4 book ai didi

asp.net-core-webapi - 如何在 ASP.NET Core 6 中使用 DateOnly/TimeOnly 查询参数?

转载 作者:行者123 更新时间:2023-12-04 16:23:50 27 4
gpt4 key购买 nike

从 ASP.NET API 中的 .NET 6 开始,如果您想获得 DateOnly(或 TimeOnly)作为查询参数,您需要单独指定它的所有字段,而不仅仅是提供一个字符串(“2021-09-14”或“10:54:53"为 TimeOnly )就像你可以为 DateTime
如果它们是主体的一部分,我可以通过添加自定义 JSON 转换器( AddJsonOptions(o => o.JsonSerializerOptions.Converters.Add(...)) )来解决这个问题,但它不适用于查询参数。
我知道这可以通过模型绑定(bind)器修复,但我不想为每个包含 DateOnly/TimeOnly 的模型创建模型绑定(bind)器。有没有办法在整个应用程序范围内修复此应用程序?
演示:
假设您有以下操作:[HttpGet] public void Foo([FromQuery] DateOnly date, [FromQuery] TimeOnly time, [FromQuery] DateTime dateTime)以下是它在 Swagger 中的表示方式:
enter image description here
我希望它表示为三个字符串字段:一个用于 DateOnly ,一个用于 TimeOnly ,另一个用于 DateTime (这个已经存在)。
PS:这不是 Swagger 的问题,而是 ASP.NET 的问题。如果我尝试手动传递 ?date=2021-09-14,ASP.NET 将无法理解。

最佳答案

事实证明,有两种解决方案:

  • 定制 ModelBinder + Swagger configuration
  • 定制 TypeConverter (Swagger 会自动看到它,并相应地更新 UI)

  • 我去了 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 将如下所示:
    enter image description here
    它是如何工作的
    首先你需要从 string 声明类型转换器至 DateOnly (还有一个从 stringTimeOnly ):
    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())

    关于asp.net-core-webapi - 如何在 ASP.NET Core 6 中使用 DateOnly/TimeOnly 查询参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69187622/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com