Je ressens votre douleur ... encore un autre format de date et d'heure ... juste ce dont vous aviez besoin !
Avec Web Api 2, vous pouvez utiliser des attributs de route pour spécifier des paramètres.
Ainsi, avec les attributs de votre classe et de votre méthode, vous pouvez coder une URL REST en utilisant le format utc qui vous pose problème (apparemment, il s'agit du format ISO8601, probablement obtenu en utilisant startDate.toISOString()).
[Route(@"daterange/{startDate:regex(^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$)}/{endDate:regex(^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$)}")]
[HttpGet]
public IEnumerable<MyRecordType> GetByDateRange(DateTime startDate, DateTime endDate)
.... MAIS, bien que cela fonctionne avec une date (startDate), pour une raison quelconque, cela ne fonctionne pas lorsque la endDate est dans ce format ... débogué pendant des heures, le seul indice est l'exception qui dit qu'elle n'aime pas les deux points " :" (même si le web.config est défini avec :
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" requestPathInvalidCharacters="" />
</system.web>
Créons donc un autre format de date (tiré du polyfill pour le format de date ISO) et ajoutons-le à la date Javascript (par souci de concision, convertissons uniquement jusqu'aux minutes) :
if (!Date.prototype.toUTCDateTimeDigits) {
(function () {
function pad(number) {
if (number < 10) {
return '0' + number;
}
return number;
}
Date.prototype.toUTCDateTimeDigits = function () {
return this.getUTCFullYear() +
pad(this.getUTCMonth() + 1) +
pad(this.getUTCDate()) +
'T' +
pad(this.getUTCHours()) +
pad(this.getUTCMinutes()) +
'Z';
};
}());
}
Ensuite, lorsque vous envoyez les dates à la méthode Web API 2, vous pouvez les convertir de chaîne en date :
[RoutePrefix("api/myrecordtype")]
public class MyRecordTypeController : ApiController
{
[Route(@"daterange/{startDateString}/{endDateString}")]
[HttpGet]
public IEnumerable<MyRecordType> GetByDateRange([FromUri]string startDateString, [FromUri]string endDateString)
{
var startDate = BuildDateTimeFromYAFormat(startDateString);
var endDate = BuildDateTimeFromYAFormat(endDateString);
...
}
/// <summary>
/// Convert a UTC Date String of format yyyyMMddThhmmZ into a Local Date
/// </summary>
/// <param name="dateString"></param>
/// <returns></returns>
private DateTime BuildDateTimeFromYAFormat(string dateString)
{
Regex r = new Regex(@"^\d{4}\d{2}\d{2}T\d{2}\d{2}Z$");
if (!r.IsMatch(dateString))
{
throw new FormatException(
string.Format("{0} is not the correct format. Should be yyyyMMddThhmmZ", dateString));
}
DateTime dt = DateTime.ParseExact(dateString, "yyyyMMddThhmmZ", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
return dt;
}
donc l'url serait
http://domain/api/myrecordtype/daterange/20140302T0003Z/20140302T1603Z
Hanselman donne quelques informations connexes ici :
http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx