I spent a good part of my day trying to get POST working with my WCF RESTful web service yesterday. Try as I might I just couldn't get my service to receive data via POST! So after a few hours of searching I finally came across the solution I needed. There isn't much information on setting all this up properly so I'm going to run through the configuration as well.
First get your configuration file ready, here's mine (By the way, I don't think the mex binding is necessary):
[code:xml]
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="FastBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="FastBehavior">
<serviceMetadata httpGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="FastBehavior" name="Fast">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/ws/fast.svc" />
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="IFast" behaviorConfiguration="FastBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
[/code]
Next throw a few attributes in your interface. First is the UriTemplate... I added a {user} parameter there but you don't have to pass any parameters through the uri if you don't want to. Second is the important part - the Method must be set to POST (in all caps). This tells WCF that the operation should only be accessible via POST, go ahead and try a GET to see for yourself.
Now here's the tricky part... Since I passed {user} as a param in the uri I can access it via "string user" but the POST data comes across as a Stream (The golden ticket!). This is the important part about sending data via POST! Check out the interface:
[code:c#]
[ServiceContract]
public interface IFast
{
[OperationContract]
[WebInvoke( UriTemplate="authorize/{user}", Method="POST" )]
Fast.SampleReturnTypes Authorize( string user, Stream postInfo );
}
[/code]
But now I need to process the POST data... luckily it's pretty simple to parse the data.
As a matter of fact in this particular scenario I used a basic form to post the data, so my data comes across in querystring key value pairs like this: keyname=value1&keyname2=value2... and so on. So you can see it would be fairly easy to parse.
However the neat thing about this is that I don't have to use a form to post the data. I can post the data from an app or AJAX and instead of using querystring values I can send XML, JSON, Base64 encoded data, etc... You can pretty much send anything! In the implementation below I use the form submitted values and with our useful HttpUtility class I can easily parse my post data:
[code:c#]
public SampleReturnTypes Authorize( string user, Stream postInfo )
{
using( StreamReader reader = new StreamReader( postInfo ) )
{
String resource = reader.ReadToEnd();
System.Collections.Specialized.NameValueCollection coll = System.Web.HttpUtility.ParseQueryString( resource );
// coll now contains your query string data
}
return new SampleReturnTypes();
}
[/code]
That should get you started in the right track! I hope it helps you!