Как сделать так, чтобы привязка параметра строки запроса WebApi сохраняла даты UTC?

Я отправляю в своей строке запроса дату UTC, например.

&EndDate=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... и, как вы можете видеть, даты не совпадают после кругового пути.

Здесь есть аналогичный вопрос, но на самом деле это не ответ (постер ответил на собственный вопрос)

Передача UTC DateTime в метод HttpGet веб-API результаты по местному времени

Какое правильное решение для решения этой проблемы? Я думаю, проблема в том, что я хочу, чтобы привязка параметров анализировала строку запроса как дату UTC. Подходит ли TypeConverter? У кого-нибудь есть полный образец того, как это сделать? Должен ли я использовать TypeConverter для всех атрибутов во всех моих классах с DateTime? Я надеялся на какую-то глобальную конфигурацию.

Спасибо.


person Raymond    schedule 24.10.2014    source источник
comment
Я обнаружил, что вопрос, на который вы ссылаетесь, имеет хороший ответ (который, по-видимому, был создан до вашего вопроса, но не был отмечен как принятый ответ, несмотря на то, что за это время он получил наибольшее количество голосов): stackoverflow.com/a/24899562/125407   -  person Johannes Rudolph    schedule 27.05.2015
comment
возможный дубликат Передача UTC DateTime в Интернет Метод API HttpGet возвращает местное время   -  person Johannes Rudolph    schedule 27.05.2015


Ответы (1)


Я решил аналогичную проблему, используя класс DateTimeOffset вместо DateTime. Пожалуйста, посмотрите на этот ответ:

DateTime и 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 в WWW

person omikad    schedule 13.12.2014
comment
См. также config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; - person Alastair Maw; 23.01.2015