.NET 6 中 DateOnly 类型的日期格式不正确

问题描述 投票:0回答:1

我在 .NET 6 API 中遇到 DateOnly 类型的问题,其中通过查询参数传递时,日期格式未正确映射。预期的日期格式为

dd.MM.yyyy
,这是挪威的标准格式,但它被解释为
MM.dd.yyyy

这是我的控制器的相关部分:

[HttpGet("data")]
public Task<IActionResult> GetData([FromQuery] DateOnly date)
{
    return Task.FromResult<IActionResult>(Ok($"Day {date.Day} Month {date.Month} Year {date.Year}"));
}

这是一个示例请求:

http://localhost:7053/data?date=01.04.2024

但是输出是:

Day 04 Month 01 Year 2024

这表明日期被解释为

Jauary 4th, 2024
,而不是
April 1st, 2024
。该应用程序的区域性设置为挪威,其中标准日期格式为
dd.MM.yyyy
。我正在寻找一种专门适用于 DateOnly 类型的解决方案,而无需诉诸使用 DateTime。我知道 DateTime 可以用作解决方法,但我需要一个坚持使用 DateOnly 的解决方案。

有人遇到过这个问题或者知道如何确保 .NET 6 中的 DateOnly 使用正确的日期格式吗?

c# asp.net .net
1个回答
0
投票

为了确保 C# 控制器中的

DateOnly
参数在从客户端发送时接收到
dd.MM.yyyy
格式的日期,您需要在 ASP.NET Core 应用程序中配置模型绑定。默认情况下,ASP.NET Core 根据服务器的区域性设置解释日期,这可能会导致场景中的日和月发生混淆。

以下是如何确保

DateOnly
参数接受指定格式的日期。您将需要创建一个自定义模型绑定器,使用
dd.MM.yyyy
格式显式解析日期。

public class DateOnlyModelBinder : IModelBinder
{
  public Task BindModelAsync(ModelBindingContext bindingContext)
  {
    if (bindingContext == null)
    {
        throw new ArgumentNullException(nameof(bindingContext));
    }

    var modelName = bindingContext.ModelName;
    var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);

    if (valueProviderResult == ValueProviderResult.None)
    {
        return Task.CompletedTask;
    }

    bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);

    var dateValue = valueProviderResult.FirstValue;

    if (string.IsNullOrEmpty(dateValue))
    {
        return Task.CompletedTask;
    }

    if (DateOnly.TryParseExact(dateValue, "dd.MM.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var date))
    {
        bindingContext.Result = ModelBindingResult.Success(date);
    }
    else
    {
        bindingContext.ModelState.TryAddModelError(modelName, "Date must be in dd.MM.yyyy format.");
    }

    return Task.CompletedTask;
  }
}

创建自定义模型绑定器后,您需要通知 ASP.NET Core 将此绑定器用于

DateOnly
类型。您可以通过创建模型绑定程序提供程序并将其添加到启动配置中的 MVC 选项来完成此操作。

public class DateOnlyModelBinderProvider : IModelBinderProvider
{
  public IModelBinder GetBinder(ModelBinderProviderContext context)
  {
    if (context == null)
    {
        throw new ArgumentNullException(nameof(context));
    }

    if (context.Metadata.ModelType == typeof(DateOnly))
    {
        return new DateOnlyModelBinder();
    }

    return null;
  }
}

在依赖注入文件中,您必须使用活页夹提供程序,如下所示:

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllers(options =>
  {
    // Add the custom model binder at the beginning of the collection
    options.ModelBinderProviders.Insert(0, new DateOnlyModelBinderProvider());
  });
}

通过实现这样的自定义模型绑定器,您可以显式控制日期格式处理并防止与不同服务器和客户端上的区域和文化设置相关的常见问题。

© www.soinside.com 2019 - 2024. All rights reserved.