Search code examples
iosjsonwcf-data-servicesodata

Invoke WCF Data Services Service Operation from iOS


How do I invoke a Service Operation in WCF from iOS?

I have a Service Operation defined in my WCF Data Service (tied to a stored procedure in my DB schema) that I need to invoke from iOS. Say I've got the following declaration in my .svc.cs file:

[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public IQueryable<Foo> GetFoos(int param1, DateTime param2, string param3)
{
  return CurrentDataSource.GetFoos(param1, param2, param3).AsQueryable();
}

And I've got it set up with the proper rights in InitializeService:

config.SetServiceOperationAccessRule("GetFoos", ServiceOperationRights.AllRead);

When I try to invoke this via HTTP POST from iOS, I get back an error wrapped in JSON:

Bad Request - Error in query syntax.

It seems like it doesn't like how I'm passing my parameters. I'm passing them JSON-encoded (using NSJSONSerialization to turn an NSDictionary into a JSON string) in the request body of a POST request. The same method works on another web service (.svc) not connected to WCF that has operations annotated the same way.

An answer to another question of mine in a similar vein suggests that data formats can be negotiated between client and server, and I've read that dates are a pain to format, so maybe it's my DateTime parameter that's a problem. But I've tried both the JSON format (\/Date(836438400000)\/ and /Date(836438400000)/) and the JSON Light format (1996-07-16T00:00:00) to no avail.

So my question is this: what is the proper way to invoke this operation? If I need to have my app tell the server what format to expect, how do I do that?

Update: I tried using the format datetime'1996-07-16T00:00:00' as mentioned in this question. Same error.

Update 2: The MSDN page for Service Operations seems to suggest that nothing besides Method = "POST" is supported when annotating the WebInvoke for a Service Operation. I tried removing everything from what is quoted in the above code and setting the method to POST. Same error.

Update 3: On Pawel's suggestion, I made a new Service Operation on my Data Service just like this:

[WebInvoke(Method = "POST")]
public IQueryable<string> GetFoos()
{
    List<string> foos = new List<string>();
    foos.Add("bar");
    return foos.AsQueryable();
}

I was able to make it work in Fiddler's Composer pane by setting the method to POST, adding accept:application/json;charset=utf-8 and Content-Length:0 to the headers. Then I added a single int parameter to the operation (called param1). I set the body of my request in Fiddler to {"param1":"1"} and ran it (and Fiddler automatically updated my content-length header), and got the same error. I changed the type of my parameter to string and ran my request again and it worked. So my problem seems to be non-string types.


Solution

  • You need to send parameters in the Url and not in the request body.