Close

June 2, 2013

“Updates are currently disabled in GET requests” exception while provisioning multiple site collections

Scenario:

Recently i was working with creating site provisioning in SharePoint 2010. For that I have a list where user submits the request for the site that needs to be created (along with some required metadata). Then I have scheduled the timer job that picks up items from that list (based on the status), iterates through the items and provisions the site.

Here is the method in Timer Job that iterates through the items and creates site collections.

public static void ProvisionSite(String siteCollectionUrl)
{
   using (SPSite siteCollection = new SPSite(siteCollectionUrl))
   {
      SPList requestList = siteCollection.RootWeb.Lists.TryGetList("SiteRequests");
      if (requestList != null)
      {
        var query = new SPQuery();

        //Fetch the items that have Status=Requested
        query.Query = String.Format("{0}", "Requested");

        SPListItemCollection items = list.GetItems(query);

        if (items != null && items.Count > 0)
            ProcessRequest(items);
      }
   }
}

//Generates random 7-digit number
public static String GenerateSiteNumber()
{
  Random random = new Random();
  String siteNumber = random.Next(0000000, 9999999).ToString();
  return siteNumber;
}

public static void ProcessRequest(SPListItemCollection items)
{
   try
   {
      foreach (SPListItem item in items)
      {
        try
        {
           SPSite site = null;
           SPSecurity.RunWithElevatedPrivileges(delegate
           {
               SPWebApplication webApp = item.Web.Site.WebApplication;
               SPSiteCollection siteCollections = webApp.Sites;

              //Generate random number to use as site collection url
              String siteNumber = GenerateSiteNumber();
              String relativeUrl = "/sites/" + siteNumber;

              //Fail if site collection already exists
              if (SPSite.Exists(new Uri("http://sp2010demo/" + relativeUrl)))
                   throw new Exception("Site already exists");

               using (SPSite newSite = siteCollections.Add(relativeUrl, "My Site" + siteNumber, "Test Site collection", 1033, null, "dc\spadmin", "",       ""))
               {
                  site = newSite;
                  //.. code removed for clarity .....
               }
           });
        }
      }
   }
   catch
   { }
}

Problem:

As provisioning is done by the timer job Context is null (i.e., HttpContext.Current will be null). In my solution, I am simply iterating through the list items and creating the site collections. First request always works fine, site is created successfully but I am getting an exception as soon as the site for the next item is being provisioned. The exception that I get is the following:

“Updates are currently disabled in GET requests. To enable updates in GET requests, change the property AllowUnsafeUpdates on SPWeb.”

Now apparently, this exception is thrown when you perform any GET operation on Web and you haven’t set AllowUnsafeUpdates to “True” !! But I’m just creating a site collection, so I don’t have any SPWeb object where I should set this property ??

After investigating a little further (and with the help of ILSpy) it turned out that after first site collection is created, HttpContext.Current is set to the context of this newly created site collection and for the next item, Context is already set to the previous site collection and exception is thrown at SiteCollection.Add() method. The Add() method basically checks if HttpContext is already set, if yes then it uses the context and in my case this is wrong!

Solution

The solution is quite easy to fix.

After the completion of first iteration, set the HttpContext to null so that during the next request there is no context set.

Here is the line of code (finally block) that I added to my previous method.


public static void ProcessRequest(SPListItemCollection items)
{
 try
 {
   foreach (SPListItem item in items)
   {
     try
     {
         //... code removed for clarity --
     }
     finally
     {
        //Reset the Context
        System.Web.HttpContext.Current = null;
     }
   }
 }
 catch
 { }
}

Hope it helps.

  • Another issue I see in this code is you are creating new site-collection. Then assign it to ‘site’ object reference and actual ‘newSite’ object is automatically got disposed because of ‘using’. If you are using this somewhere else then you are trying to used already disposed objects then it might be throwing warnings or making some uncertanities etc.

    using (SPSite newSite = siteCollections.Add(relativeUrl, “My Site” + siteNumber, “Test Site collection”, 1033, null, “dcspadmin”, “”, “”))
    {
    site = newSite;
    //.. code removed for clarity …..
    });

    Or you might be getting this type or stuff in ULS log

    Detected use of SPRequest for previously closed SPWeb object. Please close SPWeb objects when you are done with all objects obtained from them, but not before. Stack trace