6

I am sending in my querystring a UTC date, e.g.

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

And my controller parameter binds it in a complex object, e.g.

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

What I've managed to figure out is that my object after parameter binding, changes my UTC date to a local date + offset. Here is a snippet of my test case

    [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);
 }

The above is failing because the output is:

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

But, the json serialization then truncates the offset and assumes it is UTC date... and as you can see, the dates don't match up post-round-trip.

There is a similar question here, but not really an answer (the poster answered is own question)

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

What is the correct solution to resolve this issue? I think the issue is that I want the parameter binding to parse the querystring as UTC a date. Is TypeConverter the way to go? Anyone have a complete sample of how to do that? Would I have to use the TypeConverter on all attribute on all my classes with DateTime? I was hoping for a global configuration of sorts.

Thanks.

Community
  • 1
  • 1
Raymond
  • 3,382
  • 5
  • 43
  • 67
  • I found the question you linked has a good answer (which appears was created before your question, but was not marked as the accepted answer despite having the most votes in the meantime): http://stackoverflow.com/a/24899562/125407 – Johannes Rudolph May 27 '15 at 07:46
  • possible duplicate of [Passing UTC DateTime to Web API HttpGet Method results in local time](http://stackoverflow.com/questions/22581138/passing-utc-datetime-to-web-api-httpget-method-results-in-local-time) – Johannes Rudolph May 27 '15 at 07:48

1 Answers1

4

I've solved similar issue by using DateTimeOffset class instead of DateTime. Please look to this answer:

DateTime vs DateTimeOffset

DateTimeOffset class stores your time zone information in additional field. So, you should change your data model class DocumentsRequest and use DateTimeOffset.

Next, you should synchronize your WebAPI formatter with the browser. I use Newtonsoft.Json library with the following settings:

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

And I registered this settings in the WebAPI registration class:

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

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

And, on the browser's side use ISO date time format:

ISO date time format in WWW

Community
  • 1
  • 1
omikad
  • 979
  • 8
  • 10