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

Ray*_*ond 6 c# datetime utc model-binding asp.net-web-api

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

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

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

    public async Task<DocumentsRequest> GetEchoFromUriDocumentsAsync(
                                            [FromUri] DocumentsRequest request)
    {
        return request; 
    }
Run Code Online (Sandbox Code Playgroud)

我设法弄清楚的是参数绑定后我的对象将我的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);
 }
Run Code Online (Sandbox Code Playgroud)

以上是失败的,因为输出是:

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

但是,json序列化然后截断偏移量并假设它是UTC日期...正如您所看到的,日期与往返后的日期不匹配.

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

将UTC DateTime传递给Web API HttpGet方法会产生本地时间

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

谢谢.

omi*_*kad 4

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

日期时间与日期时间偏移

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

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

var jsonSettings = new JsonSerializerSettings
{
    // Note the ISO format
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    DefaultValueHandling = DefaultValueHandling.Include,
    TypeNameHandling = TypeNameHandling.Auto
}
Run Code Online (Sandbox Code Playgroud)

我在 WebAPI 注册类中注册了此设置:

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

        config.Formatters.Remove(config.Formatters.XmlFormatter);
        config.Formatters.JsonFormatter.SerializerSettings = jsonSettings;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

WWW 中的 ISO 日期时间格式