I spent waaaaaay too much time on this problem yesterday and wanted to share the solution, or more accurately, the workaround.
I’m creating an Azure hosted Data Service and to as a consumer, an Azure hosted MVC application.
My app allows users to query, create, edit and delete data.
I have the permission set properly in the data service. In fact, in desperation I completely opened up the service’s permissions with
config.SetEntitySetAccessRule("*", EntitySetRights.All);
But calling SaveChanges when there was a modification or delete involved always threw an error: Access is Denied and in some situations a 404 page not found.
When you develop Azure apps in Visual Studio, you do so with Visual Studio running as an Admin and the Azure tools use IIS to host the local emulator. I so rarely develop against IIS anymore. I mostly just use the development server (aka cassini) that shows up as localhost with a port number, e.g., localhost:37.
By default IIS locks down calls to POST, MERGE and DELETE (e.g. update and delete).
It took me a long time to even realize this but Chris Woodruff asked about that.
So I went into IIS and even saw that “All Verbs” was checked in the Handler Mappings and decided that wasn’t the problem.
Eventually I went back and explicitly added PUT, POST,MERGE,DELETE, GET in the verbs list.
But the problem still didn’t go away.
I deployed the app to see if Azure would have the same problem and unfortunately it did.
I did a lot of whining (begging for ideas) on twitter and some email lists and none of the suggestions I got were panning out.
Today I was very fortunate to have Shayne Burgess and Phani Raj from Microsoft take a look at the problem and Phani suggested to use the workaround that the WCF Data Services team created for this exact problem – when POST is being honored (e.g. insert) but PUT, MERGE and DELETE are being rejected by the server.
There is a property on the DataServiceContext called UsePostTunneling.
Setting it to true will essentially trick the request into thinking it’s a POST and then when the request got the server, saying “haha, just kidding it’s a MERGE or DELETE”. (My twisted explanation…Phani’s was more technical.)
This did the trick both locally and on Azure. But it is a workaround and our hope is to eventually discover the root cause of the problem.
Here’s a blog post by Marcelo Lopez Ruis about the property:
http://blogs.msdn.com/b/marcelolr/archive/2008/08/20/post-tunneling-in-ado-net-data-services.aspx
Hopefully my blog post has some search terms that will help others find it who have the same problem. In all of the searching I did, I never came across post tunneling though I do remember seeing something about flipping POST and PUT in a request header but the context was not inline with my problem enough for me to recognize it as a path to the solution.