I'm sure many, many, many of you have seen my old friend (okay, exception) that goes something like this: "The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again." It's like the jelly of the month club – it's the gift that keeps on giving. This problem commonly crops up when you are trying to add an item to a list…often in the guts of a RunWithElevatedPrivileges delegate. Now many folks have found some common problems and common work arounds:
- Common problems – using RunWithElevatedPrivileges, but using a pre-existing SPSite or SPWeb context. No joy there because your existing SPSite or SPWeb context doesn't enjoy the privileges of the subsequently invoked RunWithElevatedPrivileges.
- Common work around – set the AllowUnsafeUpdates property on the SPWeb to true, add your item to the list, then set the property back to false. Okay, it works, but it generally makes me feel like I over-indulged on July's jelly (you know…from my jelly of the month club?? Stick with me here).
The rather uncommon work-around I found was in a similar situation – I was using a custom page for the _layouts directory and in the code-behind I was adding a list item. I got it working the quick and yucky way in about 2 minutes because I've seen this problem so many times before (like dating back to SharePoint 2003 when they added the FormDigest control). This time though I wanted to dig into a bit more to see if I could find an alternative. This time I did.
As it turns out, you can call SPUtility.ValidateFormDigest() right before you start your RunWithElevatedPrivileges code. That gets the form validation code in the stack and lets the add continue successfully. In my particular case I was inheriting from LayoutsPageBase and my aspx markup was configured like any other _layouts page, in that it used a master page that already contained a <form> element and a <FormDigest> control instance. If you are missing either of these in your page or master then you will need to add them as well. The AllowUnsafeUpdates code is not needed any longer and so the whole page and process is just that much safer. Take a look at this approach the next time you are working in a similar scenario.