【问题标题】:Http Query Parameters in UTC in AspNet CoreAspNet Core 中 UTC 的 Http 查询参数
【发布时间】:2019-12-16 02:03:42
【问题描述】:

我遇到了一个我无法解决的问题。

我尝试在服务器端处理 UTC DateTime。

我有一个带有端点的 AspNetCore Mvc 应用程序,该端点接受可能包括 DateTimes 的查询。我希望 Mvc 了解这些日期已经在 UTC 中,而不是“再次”转换它们。

我的系统在西班牙,(UTC +2)

如果我像这样向我的 localhost 服务器发送一个 http 请求:

http://localhost:50004/api/Resources?appliesOn=2018-06-30T18:00:00.000Z

我希望将反序列化的日期时间设置为 UTC,表示与以下日期相同的日期:

DateTime.SpecifyKind(new DateTime(2018, 6, 30, 18, 0, 0), DateTimeKind.Utc)

但我可以看到 Mvc 总是将日期 2018-06-30T18:00:00.000Z 转换为两个小时后:2018-06-30 20:00:00

我试图告诉 Mvc 使用 UTC json 序列化器/反序列化器,但没有任何改变:

services
  .AddMvc()
  .AddJsonOptions(options =>
  {
      options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  });

有没有办法在 http GET 请求中发送查询参数作为 UTC 日期时间的表示?我理解 ISO 8601 中的日期,如果它有后缀 Z,则表示“零偏移”,应该已经解释为 UTC 日期时间。为什么 Mvc 会对此进行转换并添加 2 小时偏移量?

任何澄清将不胜感激!

PS:这是我的端点,你可以看到没有什么特别的:

[HttpGet("")]
public IActionResult GetResources()
{
    var displayUri = Request.GetDisplayUrl();
    var requestUri = new Uri(displayUri);
    var filter = _filteredRequestFactory.Create(requestUri);
    var resources = _myProjection.GetResourcers(filter);
    return Ok(resources);
}

【问题讨论】:

    标签: c# datetime asp.net-core-mvc utc iso8601


    【解决方案1】:

    在查询中使用 UTC 日期时间时,即使使用 ASP.NET-Core 3.1,此问题仍然存在。例如[FromQuery]

    在这个github-issue 中提供的也是一个很好用的模型绑定器。

    基本上你可以复制粘贴然后注册

    仅适用于 Web-API 控制器:

    services.AddController(options => options.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider());
    

    对于成熟的 MVC 管道

    services.AddMvc(options => options.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider());
    

    【讨论】:

      【解决方案2】:

      感谢another question in StackOverflow我发现发生这种情况的原因是因为AspNetCore Mvc反序列化器甚至没有在GET http请求中使用Json.Net反序列化器来反序列化查询参数。

      因此,以下请求: http://localhost:50004/api/DateTests?date=2018-06-15T18:00:00.000Z

      将被我的端点捕获:

      [HttpGet("")]
      public IActionResult GetDate(DateTime date)
      {
          return Ok(date.ToString("o"));
      }
      

      并以 ISO 8601 格式返回日期,如下所示:2018-06-15T20:00:00.0000000+02:00

      它反序列化查询参数,就好像它是本地时间日期一样,它应用 UTC + 2(因为应用程序在西班牙)。

      我需要一种方法来告诉 AspNet Core Mvc 反序列化器了解看起来像日期的查询参数应该已经被视为 UTC 日期,并且在反序列化时不对其进行修改。

      答案是创建一个自定义模型绑定器并将其应用于该端点或全局。

      我找到了good implementation,在添加了模型绑定器提供程序和模型绑定器后,

      我的端点现在返回 ?date=2018-06-15T18:00:00.000Z 的请求:

      2018-06-15T18:00:00.0000000 作为 UTC 类型的 DateTime。

      如果我通过 ?date=2018-06-11T18:00:00+0100 ,它将作为本地时间类型检索,结果将是: 2018-06-11T19:00:00.0000000+02:00

      根据需要

      【讨论】:

        猜你喜欢
        • 2018-12-30
        • 2020-11-20
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多