11

I have simple function on the DataService that get DateTime parameter

[WebGet]
public IQueryable<Job> LoadJobsByDate(DateTime startDate, DateTime endDate)
{
    var context = this.CurrentDataSource;

    var jobs = from j in context.Jobs
               where j.CreatedDate >= startDate && j.CreatedDate <= endDate
               select j;

    return jobs;
}

What ever syntax I'm try to send I get error.

I tried

var query1 = newContext.CreateQuery<Job>("LoadJobsByDate")
             .AddQueryOption("startDate", 
                 string.Format ("'{0:yyyy-MM-ddTHH:mm:ss}'", DateTime.Now));  

or:

var query1 = newContext.CreateQuery<Job>("LoadJobsByDate")
             .AddQueryOption("startDate", 
                 string.Format ("'datetime{0:yyyy-MM-ddTHH:mm:ss}'", DateTime.Now));  

Please advice

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
shlomi
  • 111
  • 1
  • 1
  • 3
  • Is there any reason you are formatting the value as a string, why not just pass in the date itself e.g. AddQueryOption("startDate",DateTime.Now)? – Pepto Apr 03 '11 at 08:14

2 Answers2

24

You can submit a DateTime object to the service through a HTTP request using the ISO 8601 timestamp format, which expresses time as yyyy-mm-ddThh:mm:ss (example: 2011-06-02T12:24:34).

Andrei Sfat
  • 8,440
  • 5
  • 49
  • 69
Hal
  • 981
  • 1
  • 9
  • 22
4

I don't think (from my tests and experiments) that you can pass parameters of type DateTime directly. After all, in the end (after all the niceties of the WCF DataService client-side proxy and its LINQ-to-WCF goodness), WCF Data Services is always getting its parameters from the URL query string, so basically, it's all just strings....

(this is in stark contrast to using the SOAP bindings for WCF - there, you can definitely use strongly typed parameters - DateTime and anything you like. But WCF Data Services is REST, it's all URL- und thus string-based)

So my conclusion is: you need to change your code to use string parameters and then converts those to DateTime inside your method:

[WebGet]
public IQueryable<Job> LoadJobsByDate(string startDate, string endDate)
{
    // some error checking needs to be done here! If 'startDate' or 'endDate'
    // are NULL or emtpy string --> fall back to a default

    // also - you might want to check into .ParseExact and define a list of valid,
    // supported date formats that you want to offer your users
    DateTime startDt = DateTime.Parse(startDate);
    DateTime endDt = DateTime.Parse(endDate);

    var context = this.CurrentDataSource;

    var jobs = from j in context.Jobs
               where j.CreatedDate >= startDt && j.CreatedDate <= endDt
               select j;

    return jobs;
}

As I mentioned in the code snippet - having to get strings and parse them into DateTime requires that you do some additional error checking on your part - it's a pain, but I think it's necessary to make sure your code doesn't break the first time someone enters no date or an invalid date format....

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Thanks I guess that the way to do it – shlomi Apr 04 '11 at 07:01
  • 1
    Maybe this was true some time ago, but it's not true now. The answer above this one is correct, ISO8601 works fine for URL parameters in a WCF REST service via URL parameters in a WebGet operation. – DomenicDatti May 21 '14 at 12:31
  • @DomenicDatti: look at the date - the answer is more than 3 years old by now. Unfortunately, SO answers don't automagically update themselves to the evolving technology .... – marc_s May 21 '14 at 19:37
  • That's precisely why I left the comment :) – DomenicDatti Aug 21 '14 at 03:23