I've got a WebAPI action that looks like so:
[Route("api/values/{id}")]
public async Task<HttpResponseMessage> Delete(string id, DateTimeOffset date) {
//do stuff
}
But when I invoke this from a HttpClient
instance, making a URL like:
string.Format("http://localhost:1234/api/values/1?date={0}", System.Net.WebUtility.UrlEncode(DateTimeOffset.Now.ToString()));
// -> "http://localhost:1234/api/values/1?date=17%2F02%2F2015+7%3A18%3A39+AM+%2B11%3A00"
I get a 400
response back saying that the non-nullable parameter date
does not exist.
I've also tried adding the [FromUri]
attribute to the parameter but it still doesn't map through. If I change it to be DateTimeOffset?
I can see it is left as null and looking at Request.RequestUri.Query
the value is there, just not mapped.
Finally I tried not doing a WebUtility.UrlEncode
and it made no different.
Pass the date as a query string parameter, like ? date=2012-12-31T22:00:00.000Z . Strip the . 000 from every request.
Answer. The passing of Date parameters is done in a very specific format, based on the International Date formatting standard. For any Cognos software , parameters specified in the URL for a date / time parameter, should not include a value for milliseconds, and this value should be set to zero.
DateTime values lack any knowledge of time zone, or lack thereof. If you need to know when things actually occurred, with more precision than just the approximate date, and you can't be 100% sure that your dates are ALWAYS stored in UTC, then you should consider using DateTimeOffset to represent your datetime values.
To send a DateTimeOffset
to your API, format it like this after converting it to UTC:
2017-04-17T05:04:18.070Z
The complete API URL will look like this:
http://localhost:1234/api/values/1?date=2017-04-17T05:45:18.070Z
It’s important to first convert the DateTimeOffset to UTC, because, as @OffHeGoes points out in the comments, the Z
at the end of the string indicates Zulu Time (more commonly known as UTC).
You can use .ToUniversalTime().ToString(yyyy-MM-ddTHH:mm:ss.fffZ)
to parse the DateTimeOffset.
To ensure your DateTimeOffset is formatted using the correct timezone always use .ToUniversalTime()
to first convert the DateTimeOffset
value to UTC, because the Z
at the end of the string indicates UTC, aka "Zulu Time".
DateTimeOffset currentTime = DateTimeOffset.UtcNow;
string dateTimeOffsetAsAPIParameter = currentDateTimeOffset.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
string apiUrl = string.Format("http://localhost:1234/api/values/1?date={0}", dateTimeOffsetAsAPIParameter);
The problem is the + (plus) char in the offset part, we should encode that.
If the offset is - (minus) no need to encode
Encoded value of +(plus) is %2B So the 2021-05-05T18:00:00+05:00 should be passed as 2021-05-05T18:00:00%2B05:00
http://localhost:1234/api/values/1?date=2021-05-05T18:00:00%2B05:00
if the offset is - (minus) then
http://localhost:1234/api/values/1?date=2021-05-05T18:00:00-05:00
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With