I have just struggled a while with a SharePoint Web Part that constantly threw an error, see below. This Web Part is creating a SharePoint list when it is first loaded by a user and it should create a list with permissions so that only the user has access to it (i.e. a personal list). This is done by breaking the role inheritance of the list using BreakRoleInheritance(false), so that no inherited roles are copied. I’ve used the method for this previously in the solution, but then this was done on a POST request and now it should do almost the same during a GET request, that is when the user navigates to the page.

All this is done under elevated privileges and looks something like this

SPSecurity.RunWithElevatedPrivileges(delegate() {
  using (SPSite site = new SPSite(url)) {
    using (SPWeb web = site.OpenWeb(url.Replace(site.Url, string.Empty))) {
      web.AllowUnsafeUpdates = true;
      Guid guid = web.Lists.Add(name, string.Empty, SPListTemplateType.DocumentLibrary);
      SPList list = web.Lists[guid];
      ...
      list.BreakRoleInheritance(false);
      ...
      list.Update();
    }
  }
});

This gives me the following error when running during a GET request.

“Updates are currently disallowed on GET requests.  To allow updates on a GET, set the ‘AllowUnsafeUpdates’ property on SPWeb.”

If I rewrite the code and change the BreakRoleInheritance(false) to BreakRoleInheritance(true)  and set the AllowUnsafeUpdates to true once again it works fine and I have to manually get rid of all the roles.

Why is it so?

If you step through the code in the working sample you will see that after the BreakRoleInheritance(true) line the AllowUnsafeUpdates property of the SPWeb object has changed to false. The AllowUnsafeUpdates property will reset to false whenever any ISecurable object changes their role definitions, and in the BreakRoleInheritance method you have a call to an internal function that invalidates the SPWeb object which resets the AllowUnsafeUpdate property.

The exception is then thrown after breaking the role inheritance and when the method tries to remove the roles from the list. I initially thought that it was the other way around and therefore was a bit confused.

So the correct way is this:

SPSecurity.RunWithElevatedPrivileges(delegate() {
  using (SPSite site = new SPSite(url)) {
    using (SPWeb web = site.OpenWeb(url.Replace(site.Url, string.Empty))) {
      web.AllowUnsafeUpdates = true;
      Guid guid = web.Lists.Add(name, string.Empty, SPListTemplateType.DocumentLibrary);
      SPList list = web.Lists[guid];
      ...
      list.BreakRoleInheritance(true);
      web.AllowUnsafeUpdates = true;
      // remove roles manually
      ...
      list.Update();
    }
  }
}};

Happy programming…

Note: there is a reason why this is implemented in this way, to prevent cross-site-scripting attacks, if you are unsure about what you are doing you should consider an alternate way of solving your problem.