Lists Web Service - I

As with SPS 2003, MOSS ships with some default web services as well. Most of them have been carried over from SPS 2003, whereas there are some that are newly introduced.
The Lists webservice offers some interesting functions to perform remote operations on the lists in a site collection. Some of the web methods that are exposed are:

  • AddAttachment ( listName As string , listItemID As string , fileName As string , attachment As base64Binary ) As string
  • AddDiscussionBoardItem ( listName As string , message As base64Binary )
  • AddList ( listName As string , description As string , templateID As int )
  • AddListFromFeature ( listName As string , description As string , featureID As guid , templateID As int )
  • ApplyContentTypeToList ( webUrl As string , contentTypeId As string , listName As string )
  • CheckInFile ( pageUrl As string , comment As string , CheckinType As string ) As boolean
  • CheckOutFile ( pageUrl As string , checkoutToLocal As string , lastmodified As string ) As boolean
  • CreateContentType ( listName As string , displayName As string , parentType As string , fields As , contentTypeProperties As , addToView As string ) As string
  • DeleteAttachment ( listName As string , listItemID As string , url As string )
  • DeleteContentType ( listName As string , contentTypeId As string )
  • DeleteContentTypeXmlDocument ( listName As string , contentTypeId As string , documentUri As string )
  • DeleteList ( listName As string )
  • GetAttachmentCollection ( listName As string , listItemID As string )
  • GetList ( listName As string )
  • GetListAndView ( listName As string , viewName As string )
  • GetListCollection ( )
  • GetListContentType ( listName As string , contentTypeId As string )
  • GetListContentTypes ( listName As string , contentTypeId As string )
  • GetListItemChanges ( listName As string , viewFields As , since As string , contains As string )
  • GetListItemChangesSinceToken ( listName As string , viewName As string , query As , viewFields As , rowLimit As string , queryOptions As , changeToken As string , contains As string )
  • GetListItems ( listName As string , viewName As string , query As , viewFields As , rowLimit As string , queryOptions As , webID As string )
  • GetVersionCollection ( strlistID As string , strlistItemID As string , strFieldName As string )
  • UndoCheckOut ( pageUrl As string ) As boolean
  • UpdateContentType ( listName As string , contentTypeId As string , contentTypeProperties As , newFields As , updateFields As , deleteFields As , addToView As string )
  • UpdateContentTypesXmlDocument ( listName As string , newDocument As string )
  • UpdateContentTypeXmlDocument ( listName As string , contentTypeId As string , newDocument As string )
  • UpdateList ( listName As string , listProperties As , newFields As , updateFields As , deleteFields As , listVersion As string )
  • UpdateListItems ( listName As string , updates As string )

Of these the last two might be the ones seeing the most usage. UpdateList and UpdateListItems, both are extremely handy when adding, modifying or deleting columns (in the case of the former) and list items (in the case of the latter). The SDK documents the usage of both but it does seem that there can be quite a few pitfalls while actually implementing these. Here are some examples:
I am using the UpdateListItems here as this is the easiest 
Creating the lists web service reference and initializing all data required for making the actual call.

PostLists.Lists lst = new TESTBED.PostLists.Lists();

lst.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Adding a new Item in this case a folder

string
strBatch = "<method id='1' Cmd='New'>" +
                  "<Field Name='ID'>New</Field>" +
                  "<Field Name='FSObjType'>1</Field>" +
                  "<Field Name='BaseName'>testFolder</Field>" +
                  "</Method>";
XmlDocument doc = new XmlDocument();
XmlElement el = doc.CreateElement("Batch");
XmlElement properties = doc.CreateElement("listproperties");
properties.InnerXml = "";
XmlElement newFields = doc.CreateElement("newFields");

XmlElement updateFields = doc.CreateElement("updateFields");
updateFields.InnerXml = "";
XmlElement deleteFields = doc.CreateElement("deleteFields");
deleteFields.InnerXml = "";

el.SetAttribute("OnError", "Continue");
el.SetAttribute("ListVersion", "0");
el.SetAttribute("PreCalc", "TRUE");
el.SetAttribute("ViewName", "{4A163CCB-3CE7-40B1-9EB5-A9568F355E3D}");
el.InnerXml = strBatch;

// the actual call

System.Xml.XmlNode node = lst.UpdateListItems("Documents", el);
MessageBox.Show(node.OuterXml);

Now let's look at the UpdateList webmethod. This is a bit complicated. So if you dont get it right the first time try try till you get it working! Hell no, just kidding.

Setting the environment:

 

PostLists.Lists lst = new TESTBED.PostLists.Lists();
lst.Credentials = System.Net.CredentialCache.DefaultCredentials;

XmlNode ndList = lst.GetList("ASampleList");
XmlNode ndVersion = ndList.Attributes["Version"];

XmlDocument xmlDoc = new System.Xml.XmlDocument();
XmlNode ndDeleteFields = xmlDoc.CreateNode(XmlNodeType.Element,"Fields", "");
XmlNode ndProperties = xmlDoc.CreateNode(XmlNodeType.Element, "List","");
XmlAttribute ndTitleAttrib = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute,"Title", "");
XmlAttribute ndDescriptionAttrib =(XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute,"Description", "");
XmlNode ndNewFields = xmlDoc.CreateNode(XmlNodeType.Element,"Fields", "");
XmlNode ndUpdateFields = xmlDoc.CreateNode(XmlNodeType.Element,"Fields", "");

ndTitleAttrib.Value = "RobinSannerList";
ndDescriptionAttrib.Value = "New_Description";

ndProperties.Attributes.Append(ndTitleAttrib);
ndProperties.Attributes.Append(ndDescriptionAttrib);

Creating a new field:

ndNewFields.InnerXml = "<Method ID='1'>" +
                       "<Field Type='DateTime' DateOnly='TRUE' DisplayName='A_New_Test_Field' FromBaseType='TRUE' Required='TRUE' Description='sometextdescription'/>" +
                       "</Method>";

Making the call:

try
{
           XmlNode ndReturn =
           lst.UpdateList("{18D0E90B-20B9-4931-96EB-5435D08532DC}",
                           ndProperties, ndNewFields, null , null,
                           ndVersion.Value);
           MessageBox.Show(ndReturn.OuterXml);
}

catch (Exception ex)
{
           MessageBox.Show("Message:\n" + ex.Message + "\nStackTrace:\n" + ex.StackTrace);

}

Updating the field:

ndUpdateFields.InnerXml = "<Method ID='2'>" +
                          "<Field Type='DateTime' Name='A_New_Test_Field' DisplayName='SomeNewName'/>" +
                          "</Method>";

Making the call:

try
{
           XmlNode ndReturn =
           lst.UpdateList("{18D0E90B-20B9-4931-96EB-5435D08532DC}",
                           ndProperties, null, ndUpdateFields, null,
                           ndVersion.Value);
           MessageBox.Show(ndReturn.OuterXml);
}

catch (Exception ex)
{
           MessageBox.Show("Message:\n" + ex.Message + "\nStackTrace:\n" + ex.StackTrace);
}

Deleting the Field:

ndDeleteFields.InnerXml = "<Method ID='3'>" +
                          "<Field Name='SomeNewName'/></Method>";

Making the call:

try
{
           XmlNode ndReturn =
           lst.UpdateList("{18D0E90B-20B9-4931-96EB-5435D08532DC}",
                           ndProperties, null, null, ndDeleteFields,
                           ndVersion.Value);
           MessageBox.Show(ndReturn.OuterXml);
}

catch (Exception ex)
{
           MessageBox.Show("Message:\n" + ex.Message + "\nStackTrace:\n" + ex.StackTrace);
}

Of course all is not so rosy while you are doing this and there are some issues that have been trudging along since SPS2003. More on this in the next post.

-Harsh