5866 Views // 0 Comments // Not Rated

SharePoint - Use WCF To Get Around AllowUnsafeUpdates Errors Elegantly

Any SharePoint developer's arch enemy is the following evil exception:

Updates are currently disallowed on GET requests. To allow updates on a GET, set the 'AllowUnsafeUpdates' property on SPWeb

There are a lot of solutions out there on the web. The most pervasive one is to do exactly what the exception says. (Which is ironic, since how often do SharePoint exceptions actually give us something to work with?)

So indeed, nine times out of ten, setting the "AllowUnsafeUpdates" property to "true" on the offending SPSite or SPWeb object does the trick. However, there are some random times when this still fails, or is not possible.

For example, I've found that setting a workflow to start automatically when an item is added to list blows up with this error if the code is on page (when we're in the context of an HTTP GET). Moving this logic to an event receiver or feature receiver will work, but that could really kludge your architecture.

In this scenario, setting AllowUnsafeUpdates doesn't work! It's as though the property is ignored. You can actually set the value to start a workflow when an item is changed just fine; autostart, however, dies! None of the other suggestions I found on the web panned out; all of them were borderline hacks to begin with.

Another problem with this situation is when there is no SPSite or SPWeb object available! How would you do this when, say, programmatically creating a new site collection? Consider the following:

Code Listing 1

  1. //create site collection
  2. SPWebApplication app = SPWebApplication.Lookup(new Uri("http://localhost"));
  3. using (SPSite site = app.Sites.Add("/newsite", "site", "description", ... ))
  4. {
  5. ...
  6. }

In this example, Line #3 blows up with our error! There's no "AllowUnsafeUpadates" on an SPWebApplication object, an we don't yet have the "site" variable in scope, so we're stuck.

But I found another workaround, which is much more elegant than anything else I've seen out there. The trick is to move the code into a WCF service library. Just create a new project in Visual Studio as such:

Visual Studio 2008 WCF Service Library Template

The beauty of this is that we can treat it just like a class library; we don't have to mess with the awful awful awful WCF configuration cluster-Fornication-Under-Carnal-Knowledge of a nightmare. And, this lends itself to a more structured architecture for your portal; it's easy in SharePoint to get sloppy and stuff too much logic in your web parts.

So move your code to a new WCF service library, build it, reference it normally in your UI project, and GAC it along side your web parts. I tried this with a normal class library project, and still got bit the GET problem. WCF must do something to remove itself from the HTTP context, all the while being referenced normally.

And since the code is all on the same server, there's no need to send anything over the wire, so, like I said, don't mess with any WCF nonsense beyond your service and operation contracts. However, you can expose your logic as an end point if you want to.

Have fun!

3 Tags

No Files

No Thoughts

Your Thoughts?

You need to login with Twitter to share a Thought on this post.