You can lead a CAML to water, but...


The current MSDN documentation contains what I might call *adequate* coverage of the use of Web Services with Windows Sharepoint Services 2.0  In the case of simple operations, such as retrieving list items, the samples are more or less useful and can be adapted for use in a local environment with few challenges.  Other operations, however, are not particularly well-documented -- especially those that involve the use of CAML (Collaborative Application Markup Language) XML Batches.  Anyone who has attempted to delve into the wacky world of CAML has certainly discovered that working in CAML is somewhat convoluted.


Additionally, the current documentation contains no sample for adding NEW list items to Windows SharePoint Services 2.0 lists using the Lists.asmx Web Service.  The docs do contain update samples for existing items, but the CAML/XML syntax required to add a new item is somewhat different, and not well outlined in the SPPTSDK. 


So, in response to a recent customer request along these lines, I put together a sample that creates a very simple item in an Events list.  This has the added bonus of covering the proper type required to add date/time values for an event.  This Web Service can be used, for example, to add items to a shared WSS events list linked to Outlook Calendars (through the UI). 


An example implementation might be an application used by employees to indicate when they will be out of the office.  A shared calendar could be setup in WSS, which end users could then link to Outlook 2003 clients (by using the Link to Outlook button in WSS).  A separate application could be created which would take employee out of office requests, compare them to the existing events to either grant or deny the request, and add the request to the shared calendar if granted.


The sample below happens to be in VB.NET, which is a rarity for me and for the SDK docs in general (both of which tend to prefer C#), and in this case was part of a Windows Application designed to demonstrate the task.  The sample assumes the inclusion of a Web Reference to the Lists.asmx Web Service, as well as a Windows Form with five (5) text boxes (four of which are single-line text boxes, and the fifth being a multi-line text box used for writing out operation results.  Text boxes 1-4 are used for user input, and cover (respectively), the URL of the WSS site, the name of the Events List, the Title of the new Item, and the Start Date of the new Event Item.  Obviously, the sample could be expanded/adapted to include more or less information.  I'm NOT getting into recurring Events in this sample, but wish you ALL the luck in the world if you want to go ahead and attempt to implement that functionality yourself.  :)



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


Me.Cursor = System.Windows.Forms.Cursors.WaitCursor



Dim sURL As String = Me.TextBox1.Text

Dim sList As String = Me.TextBox2.Text

Dim sTitle As String = Me.TextBox3.Text

Dim sDate As String = Me.TextBox4.Text


Dim sDisplay As String = Me.TextBox5.Text


Dim sBatch As String = ""


Dim oListWS As New AddEventItemWSVB.localhost.Lists


oListWS.Credentials = System.Net.CredentialCache.DefaultCredentials


If (oListWS.Url.EndsWith("/")) Then

     oListWS.Url = sURL.Concat(sURL, "_vti_bin/lists.asmx")


     oListWS.Url = sURL.Concat(sURL, "/_vti_bin/lists.asmx")

End If


sBatch = "<Method ID=""1"" Cmd=""New"">"

sBatch += "<Field Name=""ID"">New</Field>"

sBatch += "<Field Name=""Title"">" + sTitle + "</Field>"

sBatch += "<Field Name=""EventDate"">" + sDate + "</Field>"

sBatch += "</Method>"


Dim xDoc As New System.Xml.XmlDocument

Dim xBatch As System.Xml.XmlElement = xDoc.CreateElement("Batch")


xBatch.SetAttribute("OnError", "Return")

xBatch.InnerXml = sBatch


Me.TextBox5.Text += "Submitting batch: " + vbCrLf + xBatch.OuterXml




     Dim xReturn As System.Xml.XmlNode = oListWS.UpdateListItems(sList, xBatch)

     Me.TextBox5.Text += vbCrLf + "Return: " + vbCrLf + xReturn.OuterXml


Catch ex As Exception


     Me.TextBox5.Text += vbCrLf + "Exception: " + vbCrLf + ex.Message


End Try


Me.Cursor = System.Windows.Forms.Cursors.Default


End Sub




Note that the Date field requires a UTC date/time following the format: yyyy-mm-ddThh:mm:ssZ.  For example, 3 PM on October 23, 2004 would be represented as: 2004-10-23T15:00:00Z.


A typical successful response from this operation (e.g., the text written out to the multi-line text box #5) is below, with some names/IDs removed to protect the guilty:




Submitting batch:

<Batch OnError="Return"><Method ID="1" Cmd="New"><Field Name="ID">New</Field><Field Name="Title">My New Event</Field><Field Name="EventDate">2004-10-08T12:00:00Z</Field></Method></Batch>


<Results xmlns=""><Result ID="1,New"><ErrorCode>0x00000000</ErrorCode><ID /><z:row ows_ID="15" ows_Title="My New Event" ows_Modified="2004-10-08 13:31:58" ows_Created="2004-10-08 13:31:58" ows_Author="1;#<DOMAIN\username>" ows_Editor="1;#<DOMAIN\username>" ows_owshiddenversion="1" ows_Attachments="0" ows__ModerationStatus="0" ows_LinkTitleNoMenu="My New Event" ows_LinkTitle="My New Event" ows_SelectTitle="15" ows_Order="1500.00000000000" ows_GUID="{F9158A44-3F57-44C1-BD87-269673F987C6}" ows_EventDate="2004-10-08 12:00:00" ows_fRecurrence="0" ows_EventType="0" xmlns:z="#RowsetSchema" /></Result></Results>




Happy Eventing!