Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing DateTimeOffset as WebAPI query string

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.

like image 805
Aaron Powell Avatar asked Feb 16 '15 20:02

Aaron Powell


People also ask

How do I pass a date as parameter in web API?

Pass the date as a query string parameter, like ? date=2012-12-31T22:00:00.000Z . Strip the . 000 from every request.

How do you pass date parameters?

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.

Is DateTimeOffset better than DateTime?

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.


2 Answers

Answer

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).

Code

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);
like image 140
Brandon Minnick Avatar answered Sep 17 '22 11:09

Brandon Minnick


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
like image 44
Sukesh Chand Avatar answered Sep 18 '22 11:09

Sukesh Chand