For quite a while I have been sending POST requests to invoke service operations, as I detailed in an earlier post Calling Service Operations Using POST. Since this post was from the pre-WCF Data Services 5.0 days, I was using HttpWebRequest to send the request as POST support for service operations had not yet been added to the client, which was done in WCF Data Services 5.0.
With support for both GET and POST service operations, I have been able to define the HTTP method for my service operations in a more conceptually correct way, by using POST ([WebInvoke(Method="POST")]) for operations with side effects (with WebGet for non-side-effecting operations). A good example of this is a POST service operation, which I describe in Send Push Notifications from an OData Service using Windows Azure Notification Hubs, that creates a new Notification Hub registration—an operation with side effects. I had published this sample on Code Gallery—everything was working fine on the previous version of the OData client for Windows Store. However, this client version is no longer being supported and cannot be installed (certificate issue), so it was time to upgrade to the WCF Data Services 5.6.0 tooling for Visual Studio 2013. I described all this in Time to get the WCF Data Services 5.6.0 RTM Tools. The weird thing is that after upgrading to this new client version and tooling, any request to a POST service operation generates the following response from the data service:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii">
<p>HTTP Error 411. The request must be chunked or have a content length.</p>
Looks like there is a breaking change going from the original OData client library for Windows Store apps to the portable library-based client in the WCF Data Services 5.6.0 tools. Some web servers (like IIS apparently) reject all POST requests that do not include the Content-Length header, returning a 411 error (unless chunked transfer is used). Because of this, the version of HttpWebRequest in some libraries (I know that Silverlight does) automatically sets this header for you based on the payload. Anyway, in the previous client version, the library must have been generating a Content-Length = 0 header correctly, since it used to work. It seems that I have stumbled upon some kind of regression in the new 5.6.0 client.
While not a major deal breaker, this is clearly an annoying regression in client functionality for folks who have just started to enjoy the goodness of support for POST service operations. The workaround is to basically go back to either using GET requests for side-effecting service operations (easy if you own the service) or compose your own HttpWebRequest (your only option if you can’t change the service). Fortunately, I have access to my data service, so it’s an easy fix for me, but what about folks who can’t change a POST service operation into a GET, or don’t want to (HttpWebRequest I suppose)? I hope that this gets fixed soon.