SPWeb.ProcessBatchData() doesn’t really take an xml string

If you look at the documentation for SPWeb.ProcessBatchData():

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.processbatchdata(v=office.12).aspx

You see that all you need to do is craft up a simple bit of xml and send to the method. Now I don’t know about you but whenever I create Xml strings in C# I usually use single quotes ‘ instead of double quotes ” for attribute values, this should of course not matter to any xml parser.

I was testing out the SPWeb.ProcessBatchData() method and wrote the following scratch console app:


namespace ScratchConsole
{
 class Program
 {
  static void Main(string[] args)
  {
   using(SPSite siteCollection = new SPSite("http://skpkapd0107:1001/"))
   using(SPWeb testSite = siteCollection.RootWeb)
   {
    SPList listToBatchUpdate = testSite.GetList("/Lists/ScratchTestList");

    StringBuilder sb = new StringBuilder();
    sb.Append("<?xml version='1.0' encoding='UTF-8'?><Batch OnError='Return'><Method ID='1'>");
    sb.AppendFormat("<SetList>{0}</SetList>", listToBatchUpdate.ID.ToString());
    sb.Append("<SetVar Name='ID'>New</SetVar><SetVar Name='Cmd'>Save</SetVar>");
    sb.Append("<SetVar Name='urn:schemas-microsoft-com:office:office#Title'>A New Item Created By SPWeb.ProcessBatchData()</SetVar>");
    sb.AppendFormat("<SetVar Name='urn:schemas-microsoft-com:office:office#ADateField'>{0}</SetVar>", SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now));
    sb.AppendFormat("<SetVar Name='urn:schemas-microsoft-com:office:office#ANumberField'>{0:d}</SetVar>", 3456);
    sb.Append("</Method></Batch>");
    string batchUpdateXml = sb.ToString();
    testSite.ProcessBatchData(batchUpdateXml);  
   }
  }
 }
}

Seems simple enough, I’m sending a single new item to a test list with a couple of extra columns (a DateTime and Number column). The problem was I was getting the following (very unhelpful) exception:

System.ArgumentException was unhandled
  Message=”Value does not fall within the expected range.”
  Source=”Microsoft.SharePoint.Library”
  StackTrace:
       at Microsoft.SharePoint.Library.SPRequestInternalClass.ProcessBatchData(String bstrUrl, String bstrData, ISPDataCallback pResultCallback)
       at Microsoft.SharePoint.Library.SPRequest.ProcessBatchData(String bstrUrl, String bstrData, ISPDataCallback pResultCallback)
       at Microsoft.SharePoint.SPWeb.ProcessBatchData(String strBatchData)
       at ScratchConsole.Program.Main(String[] args) in J:\code\Homechoice\spikes\rippeyc\ScratchConsoleSolution\ScratchConsole\Program.cs:line 37
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

 Just no idea what the problem was supposed to be. After staring at the screen and the documentation for SPWeb.ProcessBatchData() I made a wee change to the code:


namespace ScratchConsole
{
 class Program
 {
  static void Main(string[] args)
  {
   using(SPSite siteCollection = new SPSite("http://skpkapd0107:1001/"))
   using(SPWeb testSite = siteCollection.RootWeb)
   {
    SPList listToBatchUpdate = testSite.GetList("/Lists/ScratchTestList");

    StringBuilder sb = new StringBuilder();
    sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch OnError=\"Return\"><Method ID=\"1\">");
    sb.AppendFormat("<SetList>{0}</SetList>", listToBatchUpdate.ID.ToString());
    sb.Append("<SetVar Name=\"ID\">New</SetVar><SetVar Name=\"Cmd\">Save</SetVar>");
    sb.Append("<SetVar Name=\"urn:schemas-microsoft-com:office:office#Title\">A New Item Created By SPWeb.ProcessBatchData()</SetVar>");
    sb.AppendFormat("<SetVar Name=\"urn:schemas-microsoft-com:office:office#ADateField\">{0}</SetVar>", SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now));
    sb.AppendFormat("<SetVar Name=\"urn:schemas-microsoft-com:office:office#ANumberField\">{0:d}</SetVar>", 3456);
    sb.Append("</Method></Batch>");
    string batchUpdateXml = sb.ToString();
    testSite.ProcessBatchData(batchUpdateXml);  
   }
  }
 }
}

And it worked, all I did was replace the single quote ‘ in the xml with a double quote “.

Looking back at the exception stack trace it makes you think that in the SPRequestInternalClass.ProcessBatchData() method there must be code that is parsing the string directly and not handing off the parsing to an xml parser. So the string you pass to the method isn’t really an xml string, it’s just a bit of text that resembles an xml string.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

3 Responses to SPWeb.ProcessBatchData() doesn’t really take an xml string

  1. Hello,

    actually, I think that the single quote must not be used for the prologue only. I often use pbd and when you use single quote in method syntax, there are no problem, but the format of the prologue must absolutely be correct. Double quota, no blank space before the last “?” or after the first “?”.

    Regards

    • finarne says:

      Thanks for the comment but the point is that even the prologue can be written to take single or double quotes, so whatever code is used to parse the incoming xml is not fully compliant with the xml spec (all the other Microsoft Xml stack technologies seem to cope with the quote variations).

  2. guru says:

    i m iterating 15000 records from excel sheet with some logic i m building xml ith 2000 records and giving it to web.processbatchdata, until it creates those items the code wont execute further to process records.. how can i add this is thread? so that i can process all data in parallel?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s