问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/26553122/how-to-have-webapi-querystring-parameter-binding-keep-utc-dates