如何让WebApi查询字符串参数绑定保持UTC日期?

时间:2014-10-24 17:25:56

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

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

  

&安培;结束日期= 2000-01-02T03%3a04%3a05.0060000Z

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

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

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

    [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?我希望有各种各样的全球配置。

感谢。

1 个答案:

答案 0 :(得分:3)

我通过使用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