【问题标题】:How to have WebApi querystring parameter binding keep UTC dates?如何让 WebApi 查询字符串参数绑定保持 UTC 日期?
【发布时间】:2014-12-20 14:22:10
【问题描述】:

我在我的查询字符串中发送一个 UTC 日期,例如

&EndDate=2000-01-02T03%3a04%3a05.0060000Z

我的控制器参数将它绑定在一个复杂的对象中,例如

    public async Task<DocumentsRequest> GetEchoFromUriDocumentsAsync(
                                            [FromUri] DocumentsRequest request)
    {
        return request; 
    }

我设法弄清楚的是,我的对象在参数绑定后将我的 UTC 日期更改为本地日期 + 偏移量。这是我的测试用例的sn-p

    [TestMethod]
    public void Should_generate_querystring_and_parameter_bind_correctly()
    {

        DocumentsRequest request = DocumentRequestBuilder.DocumentsRequest();
        string queryString = ReflectionQueryStringConverter.ToQueryString(request);

        string baseUrl = "http://baseUrl/Test/EchoFromUriDocuments";
        string uri = baseUrl + queryString;
        HttpResponseMessage response = _client.GetAsync(uri).Result;
        string outputString = response.Content.ReadAsStringAsync().Result;

        JsonSerializer<DocumentsRequest> serializer = 
            new JsonSerializer<DocumentsRequest>();
        DocumentsRequest output = serializer.DeserializeFromString(outputString);

        output.EndDate.Should().Be(request.EndDate);
 }

以上失败,因为输出是:

2000-01-01T19:04:05.006-08:00

但是,json 序列化随后会截断偏移量并假定它是 UTC 日期...如您所见,日期在往返后不匹配。

这里有一个类似的问题,但不是真正的答案(发帖者回答的是自己的问题)

Passing UTC DateTime to Web API HttpGet Method results in local time

解决此问题的正确解决方案是什么?我认为问题是我希望参数绑定将查询字符串解析为 UTC 日期。 TypeConverter 是要走的路吗?任何人都有如何做到这一点的完整示例?我是否必须在我的所有类的所有属性上使用 DateTime 的 TypeConverter?我希望有一个全局配置。

谢谢。

【问题讨论】:

标签: c# datetime asp.net-web-api model-binding utc


【解决方案1】:

我已经通过使用 DateTimeOffset 类而不是 DateTime 解决了类似的问题。请看这个答案:

DateTime vs DateTimeOffset

DateTimeOffset 类将您的时区信息存储在附加字段中。因此,您应该更改数据模型类 DocumentsRequest 并使用 DateTimeOffset。

接下来,您应该将 WebAPI 格式化程序与浏览器同步。我使用具有以下设置的 Newtonsoft.Json 库:

var jsonSettings = new JsonSerializerSettings
{
    // Note the ISO format
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    DefaultValueHandling = DefaultValueHandling.Include,
    TypeNameHandling = TypeNameHandling.Auto
}

我在 WebAPI 注册类中注册了这个设置:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        ...

        config.Formatters.Remove(config.Formatters.XmlFormatter);
        config.Formatters.JsonFormatter.SerializerSettings = jsonSettings;
    }
}

并且,在浏览器方面使用 ISO 日期时间格式:

ISO date time format in WWW

【讨论】:

  • 另见config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
猜你喜欢
  • 2013-06-28
  • 1970-01-01
  • 2021-09-07
  • 2018-05-25
  • 2015-11-19
  • 2021-04-19
  • 1970-01-01
  • 2021-08-21
  • 1970-01-01
相关资源
最近更新 更多