PerfectForms SharePoint Integration Accessing Lists from PerfectForms AUTHOR: KEITH LEWIS DATE: 6/15/2011 Date of Last Revision: 6/15/11 Page 1 of 16
Contents Introduction... 3 Purpose... 3 Querying SharePoint using XPath A Walkthrough... 4 Create a Web Services Connection... 4 Create a Query Request Action... 5 Using the Connection... 7 Improving Presentation Sorting the Response... 8 Querying By Field Values... 9 Retrieving Only a Few Fields... 11 Advanced List Manipulation... 12 Creating the Connection... 12 Getting a List of the Available Lists... 12 Getting All Records in a List... 12 Getting Only Certain Records from a List... 12 Adding a Row to a List... 14 Appendix A PerfectForms XPath... 15 SOAP Header and Body Elements... 15 Attributes... 15 Appendix B Determining the GUID of a list in SharePoint... 16
Introduction Purpose With the release of Version 2.0 of PerfectForms, it is now possible to access the Microsoft SharePoint API Web services from within your form. This document shows you how to use two of the SharePoint APIs from your form: Querying lists using XPath (dspsts.asmx) This is most useful when you have data held in SharePoint lists that you wish to use in your PerfectForms project, such as for populating dropdowns or lists. Although it requires knowledge of xpath, it can be used quite effectively with no knowledge of CAML. Accessing and Manipulating Lists (list.asmx) While it is possible to obtain data from SharePoint lists using dspsts.asmx, it is a query-only interface. List.asmx provides much richer functionality, but requires an understanding of CAML and how to produce a CAML query in PerfectForms. Date of Last Revision: 6/15/11 Page 3 of 16
Querying SharePoint using XPath A Walkthrough In this section, we take you through configuring a connection and using it to populate a dropdown from data held in a SharePoint list. The list we are using is a list of departments in a fictional company: Figure 1 Departments List in SharePoint PerfectForms cannot interpret the WSDL produced by dspsts.asmx so we have to manually configure the connection and its actions. Create a Web Services Connection Complete the steps below to create a Web Services connection. 1. Enter the details for the connection. Service URL URL Encode Params Use Proxy http//yoursharepoint.yourdomain.com/_vti_bin/dspsts.asmx Yes Yes (Currently required for authentication.) 2. Specify the Service WSDL information. Implementation WSDL URL.NET Leave this blank. Date of Last Revision: 6/15/11 Page 4 of 16
Use Proxy Yes (Currently required for Authentication) 3. Provide basic authentication details. Username Password a user that has access to the SharePoint list(s) you wish to query http//yoursharepoint.yourdomain.com/_vti_bin/dspsts.asmx?wsdl 4. Save the connection. Create a Query Request Action Once the connection has been created, you must create a new action. To create this new action, complete the steps below. 1. Specify the type as XML Result. 2. Select SOAP under Service Method. This will produce the following error message: Figure 2 Error message getting WSDL from dspsts.asmx 3. Click OK on the error message dialog. The service operation will now be editable. Enter queryrequest. 4. Under Send Parameters enter the following for a Simple Query: RequestDocument RequestMethod Requestspace Versionsspace Version Query Service Parameter *request@document *request@method *request@xmlns *versions@xmlns *versions.version dsquery@select Table 1 Send Parameters for a Simple Query Date of Last Revision: 6/15/11 Page 5 of 16
5. Apply Changes, then click Test and enter the following values to be used to query the Department List: Value RequestDocument content RequestMethod query Requestspace http://schemas.microsoft.com/sharepoint/dsp Versionsspace http://schemas.microsoft.com/sharepoint/dsp Version 1.0 Query 1 /list[@id='{86c369dc-2d59-4a19-857c-c99912dc6b6b}'] Table 2 Parameter Values to Query the Departments List Apart from the query value, the values never change. To load from your own list, you will need to find the GUID for the list you wish to query (see Appendix B). 6. After entering the values listed above click Connect. The SOAP response will be displayed in the Result Log. 7. Close the Test Action form and click Auto Complete for the return parameters. You will be prompted for a sample response that has already been populated with the response from your previous test: Figure 3 SOAP Response Example Used to Auto Complete Return Fields 1 The query can be any XPath that refers to a list e.g. /list[@name= Announcements ] Date of Last Revision: 6/15/11 Page 6 of 16
8. Click OK and return parameters will be added for every node in the SOAP response body. Many of these nodes will be of no use to us and can be deleted. 9. In this case, we want the following return parameters (so remove the others): XPath 2 Title dsqueryresponse.departments.departments_row.title Manager dsqueryresponse.departments.departments_row.manager Manager_x0020_Email dsqueryresponse.departments.departments_row.manager _x0020_email ID dsqueryresponse.departments.departments_row.id Modified dsqueryresponse.departments.departments_row.modified Table 3 Return Parameters Note: In the SharePoint list, the Manager Email column has a space in its name. Since this is not valid in the XML response, the space has been replaced with _x0020_ (the 16 bit hexadecimal character code for space). Some other characters are also escaped similarly. This is documented in the SharePoint Dirty Characters blog. Using the Connection Once you have applied your changes, your new connection is ready for use on a form. Your form developer must supply the SharePoint query values using a formula as shown in the images below. Figure 4 Connect Command to Populate a Dropdown 2 PerfectForms uses a modified version of XPath to reference a node in an XML Document (See Appendix A) Date of Last Revision: 6/15/11 Page 7 of 16
Figure 5 Example of Using a Formula to Pass a Fixed Value The values for each Send Parameter should be entered as shown in Table 2. In this example, the Department drop-down is populated with Title in its caption and ID in its Value. Figure 6 A Dropdown Populated from a SharePoint List Improving Presentation Sorting the Response As you can see, the departments are not listed alphabetically. We can ask SharePoint to sort the result set by a specified column. To do this, we add the following parameters to the SOAP Call: Order OrderType OrderDirection Service Parameter dsquery.query.orderby.orderfield@ dsquery.query.orderby.orderfield@type dsquery.query.orderby.orderfield@direction Date of Last Revision: 6/15/11 Page 8 of 16
Table 1 Additional Send Parameters to Sort the Result Set Apply changes and test the action with the following values: Value RequestDocument content RequestMethod query Requestspace http://schemas.microsoft.com/sharepoint/dsp Versionsspace http://schemas.microsoft.com/sharepoint/dsp Version 1.0 Query /list[@id='{86c369dc-2d59-4a19-857c-c99912dc6b6b}'] Order Title OrderType xsd:string OrderDirection ASC Table 5 Parameter Values For Retrieving A Sorted Result Set Order is the name of the field to sort by (remember to escape the spaces and other characters as necessary). OrderType is the data type of the Field you are sorting by. Possible values are documented in the Microsoft documentation for dspsts. OrderDirection can be either ASC or DESC. Add these additional values to the Connect command in the form and preview: Figure 7 Departments Are Now Sorted Querying By Field Values In addition to populating a list or drop-down from a SharePoint list, you may also need to look up one or more entries from the list depending on the value of a field. Using our example, you may want to look up the staff in a department selected in the drop-down. To do this, we create another action on our connection in the same way as above. The new action has the following Service Parameters: RequestDocument Service Parameter *request@document Date of Last Revision: 6/15/11 Page 9 of 16
RequestMethod Requestspace Versionsspace Version Query Field Value ValueType AllFields RowLimit *request@method *request@xmlns *versions@xmlns *versions.version dsquery@select dsquery.query.where.eq.fieldref@ dsquery.query.where.eq.value dsquery.query.where.eq.value@type dsquery.query.fields.allfields dsquery.query@rowlimit This implements a simple where clause testing a single field for equality. More complex where clauses can be constructed using AND and OR constructs (see the Microsoft CAML Query Schema Web site page for additional information). Apply Changes and test with the following values: Value RequestDocument content RequestMethod query Requestspace http://schemas.microsoft.com/sharepoint/dsp Versionsspace http://schemas.microsoft.com/sharepoint/dsp Version 1.0 Query /list[@id='{5108588e-7740-445b-8c4f-8ae0b11948e4}'] Field Department Value Accounts ValueType text Again, Auto Complete the Return Parameters and remove the unnecessary fields. In our example, we have the following return parameters: Surname Forename Extension Office Full email XPath dsqueryresponse.staff.staff_row.title dsqueryresponse.staff.staff_row.forename dsqueryresponse.staff.staff_row.extension dsqueryresponse.staff.staff_row.office dsqueryresponse.staff.staff_row.full_x0020_ dsqueryresponse.staff.staff_row.email Date of Last Revision: 6/15/11 Page 10 of 16
This can be sorted as shown above. Retrieving Only a Few Fields The examples above will return all fields from the selected rows in the list. It is also possible to restrict the columns returned using the following Service Parameters. Field1 Field1 Field2 Field2 Field3 Field3 Field4 Field4 Service Parameter dsquery.query.fields.field dsquery.query.fields.field@ dsquery.query.fields.field dsquery.query.fields.field@ dsquery.query.fields.field dsquery.query.fields.field@ dsquery.query.fields.field dsquery.query.fields.field@ Date of Last Revision: 6/15/11 Page 11 of 16
Advanced List Manipulation While dspsts.asmx provides a simple interface that can only retrieve data from SharePoint, List.asmx has a far more feature-rich interface. However, for all but the simplest of operations, an understanding of CAML (Collaborative Application Markup Language) is required. For more information on CAML, you can review the Microsoft article titled Introduction to Collaborative Application Markup Language. The examples below are not exhaustive, but by following the examples, someone experienced in the use of the Lists.asmx API should be able to perform most operations using PerfectForms. Creating the Connection PerfectForms is able to interpret the WSDL from lists.asmx, so creating a connection is straightforward. You can review this process in the Creating PerfectForms Connections topic of the PerfectForms Help Guide. You should, however, select Use Proxy and supply credentials for Basic Authentication. Getting a List of the Available Lists Create an action on your Lists connection: Type Service Method Operation XML Result SOAP GetListCollection Apply Changes and test the action, then auto-complete the Return Parameters. It should be noted that you may not need all the fields that are returned. You may remove any return parameters you feel are not needed. Getting All Records in a List Create an action on your Lists connection: Type Service Method Operation XML Result SOAP GetListItems Add a single Send Parameter called list. Apply Changes and test the action using the name of the list (do not escape any spaces, etc). Next auto-complete the Return Parameters and remove those that are not needed. Getting Only Certain Records from a List Date of Last Revision: 6/15/11 Page 12 of 16
This example retrieves rows from a calendar list that fall between two dates. Create an action on your Lists connection: Type Service Method Operation XML Result SOAP GetListItems list DateFromRef DateFromValue DateFromType DateToRef DateToValue DateToType Service Parameter list query.query.where.and.geq.fieldref@ query.query.where.and.geq.value query.query.where.and.geq.value@type query.query.where.and.leq.fieldref@ query.query.where.and.leq.value query.query.where.and.leq.value@type This builds to the following CAML in the soap query: <query> <Query> <Where> <And> <Geq> <FieldRef = [DateFromRef] /> <Value Type= [DateFromType] > [DateFromValue] </Value> </Geq> <Leq> <FieldRef = [DateToRef] /> <Value Type= [DateToType] > [DateToValue] </Value> </Leq> </And> </Where> </Query> </query> Apply Changes and test using the name of the list (do not escape any spaces, etc) and values similar to those in the table below. Next, auto-complete the Return Parameters and remove those that are not needed. list DateFromRef DateFromValue DateFromType DateToRef DateToValue DateToType Value Calendar EventDate A date in the format YYYY-mm-ddThh:mm:ss DateTime EventDate A date in the format YYYY-mm-ddThh:mm:ss DateTime Date of Last Revision: 6/15/11 Page 13 of 16
Adding a Row to a List Create an action on your Lists connection: Type Service Method Operation XML Result SOAP UpdateListItems list Value 1 Field 1 Value 2 Field 2 Value 3 Field 3 Value 4 Field 4 updates.batch.method@id updates.batch.method@cmd updates.batch@onerror Service Parameter list updates.batch.method.field updates.batch.method.field@ updates.batch.method.field updates.batch.method.field@ updates.batch.method.field updates.batch.method.field@ updates.batch.method.field updates.batch.method.field@ updates.batch.method@id updates.batch.method@cmd updates.batch@onerror Apply Changes and test using the name of the list (do not escape any spaces, etc) and values similar to those in the table below. Next, auto-complete the Return Parameters and remove those that are not needed. Value list Calendar Value 1 A date in the format YYYY-mm-ddThh:mm:ss Field 1 StartTime Value 2 A date in the format YYYY-mm-ddThh:mm:ss Field 2 EndTime Value 3 An Event Field 3 Title Value 4 An Organiser Field 4 BookedBy updates.batch.method@id 1 updates.batch.method@cmd New updates.batch@onerror Continue Date of Last Revision: 6/15/11 Page 14 of 16
Appendix A PerfectForms XPath In PerfectForms, all references to XPath refer to a proprietary language loosely based on the XPath standard. The main difference is that / is replaced with. and that all paths are absolute. SOAP Header and Body Elements A node in a SOAP Header is referenced to by prefixing the path with an asterisk. So for the following SOAP Envelope: <soap:envelope xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:header> <request document="content" method="query" xmlns="http://schemas.microsoft.com/sharepoint/dsp" /> <versions xmlns="http://schemas.microsoft.com/sharepoint/dsp"> <version>1.0</version> </versions> </soap:header> <soap:body> <queryrequest xmlns="http://schemas.microsoft.com/sharepoint/dsp"> <dsquery select="/list[@id='{86c369dc-2d59-4a19-857c-c99912dc6b6b}'] > </dsquery> </queryrequest> </soap:body> </soap:envelope> *request refers to request element in the SOAP Header. dsquery refers to the dsquery element in the SOAP body. Attributes Just as in standard XPath, attributes are indicated using an @ symbol. This symbol should not be prefixed by a period. In the above SOAP request, *request@document refers to the document attribute of the request element in the SOAP Header, which has a value of content. In addition, dsquery@select refers to the select attribute of the dsquery element in the body of the SOAP request. <Fields> <Field id= field1 >Value1</Field> <Field id= field2 >Value2</Field> <Field id= field3 >Value3</Field> </Fields> An attempt to produce the above results in all fields having the same ID (the last value set). This has implications for updating SharePoint Lists and for specifying the fields that should be returned from a list. Date of Last Revision: 6/15/11 Page 15 of 16
Appendix B Determining the GUID of a list in SharePoint While it is possible to use the Lists.asmx API to iterate the lists and determine the GUID of any given list, it is unlikely that your forms will need to determine the GUID at run-time. Doing so would degrade performance of your form. Alternatively, while accessing a list from a browser you can determine the GUID in a more straightforward manner: 1. Connect to your SharePoint portal. 2. Open the list you wish to access. 3. On the Settings menu select List Settings 4. The list customization page will display. 5. Look in the address bar and you will see the List ID: 6. Copy the GUID and substitute for the GUID s given in this document. Date of Last Revision: 6/15/11 Page 16 of 16