Sunday, August 1, 2010

Connecting to SharePoint 2007 Web Services

Hi All, 

SharePoint gives the flexibility to write custom web services for developers as well as an ensemble of out-of-the-box web services. Developing SharePoint custom application could involve programming aspects such as object model, web services, XML, etc. If we consider SharePoint's object model, we can do most of the programmatic access in SharePoint. Its far more robust and has an array of features that developer could leverage on. But object model lacks support for remote operations and applications. Whereas, Web Services part supports interoperability and developers could use this technique to communicate with non-SharePoint applications. As we know that Web Services is platform independent and could be developed in Java, ColdFusion, JSP besides .NET. 

Where Web Services resides in SharePoint 2007 and SharePoint 2010?

In SharePoint 2007 context, SharePoint web services are implemented as ASP.NET web services and could be found in 12 hive i.e. "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI". When a new SharePoint site is provisioned, a virtual directory named "_vti_bin". Therfore, if want to have all the list web services (lists.asmx) methods for a specific site then just type in:

http://sp2007:4848/_layouts/_vti_bin/lists.asmx



In SharePoint 2010 context, follows exactly same concepts. In 14 hive, we will find a new folder named "WebServices" that contains additional web services and WFC services.


   
Advantage of Web Services over Object Model in SharePoint 2007? 

There are specialized query that can be used ONLY using web services. Let's take a simple example.  

a) Querying list with multiple folders:
 
Lets create a document library called "IT System Checklists" that contains lot of folders within. This is full structure:

Shared Documents (Main document library)
---------Cars (sub-folder)
----------------------BMW (sub-sub-folders)
----------------------Mercedes Benz
----------------------Ferrari
----------------------Lamborghini
---------Scooters (sub-folder)
----------------------(Same structure )

What I have to search for each folder and do some kind of manipulations. If we use U2U builder,

>>Choose the Site URL: http://testserver/apac/Tools
>>Choose "Connect via Object Model"









>> Right click on the "Shared Documents". We have just option "Query". If we query this list "ID" and order by, there will be just 2 rows i.e. "Cars" and "Scooters". There is no folders like BMW, Mercedes Benz, Ferrari folders etc.











But, we can choose second option: "Connect via SharePoint Web Services"








>> Right click on "Shared Documents", select "GetListItems" and choose "Query Options" tab.
Here we can select any sub folder.













Besides, folders there are other queries which object model could not handle. 
b) Query with DataTime values
c) Query with Calendar lists

A very detailed and extremely useful article by Karine Bosch (from U2U).

SharePoint web services can be leveraged in two ways:
a) Out-of-the-box web services: Utilize and manipulate our code.
b) Custom Web Services: Write our own implementation.    

Now, lets get our hands dirty and write a Window Application that display all the lists in a specific site and when a specific list with its contents. If a list does not have any list items then we display a message to the user.

Step1:  Create a new Visual Studio 2008/2010 project, File >> New >> Project >> Select "Windows Forms Application" and name the project: "WINWebServices"


Step2: Drag a listbox control named "lstSPLists", two group boxes and a GridView as show illustrated below:


Step3: Right click on the "WINWebServices" project and under "References" folder select the "Add Service Reference"

Step4:In the "Add Service Reference" window, click on "Advanced..." button


Step5: Click on "Add Web Reference" button.


Step6: Type in the location of list web service i.e.

http://sp2010:4848/_layouts/_vti_bin/lists.asmx

. Configure the "Web reference name" as "ListService"and click on "Add Reference". When we click on this button a windows authentication will be required and pass the login credentials.   


Step7: Now, we are connected to list web service. We have to populate the "lstSPLists" and use list web service "GetListCollection" method which displays all the lists for a specific site. "GetListCollection" accepts a string and listBox accepts an object. We define a class named: "GetListCollectionItem":

public class GetListCollectionItem
        {
            private String title;

            public String Title
            {
                get { return title; }
                set { title = value; }
            }

            private Guid theGuid;

            public Guid TheGuid
            {
                get { return theGuid; }
                set { theGuid = value; }
            }

            public GetListCollectionItem(string disp, Guid id)
            {
                title = disp;
                theGuid = id;
            }

            public override string ToString()
            {
                return Title;
            }

  }

Step8: Go to designer, select the windows form and double click to get a "Form1_Load"and when a form is loaded then all the lists will be populated automatically in "lstSPLists" control.

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {

                // Create an instance of the Web service proxy class.
                ListService.Lists listWS = new ListService.Lists();
                listWS.Credentials = CredentialCache.DefaultCredentials;

                // 1) Call the List service "GetListCollection" method
                XmlNode node = listWS.GetListCollection();

                //Loop all the lists for this site and populate in the "lstSPList" control
                foreach (XmlNode n in node.ChildNodes)
                {
                    lstSPLists.Items.Add(new GetListCollectionItem(n.Attributes["Title"].Value, new Guid(n.Attributes["ID"].Value)));
                }
            }
            catch (WebException ex)
            {
                MessageBox.Show("Message: " + ex.Message + "InnerException: " + ex.InnerException);
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                MessageBox.Show("Message: " + ex.Message + "InnerException: " + ex.InnerException);
            }
        }


Build the project and press F5 to view the application. 



Step9: Next step is to double click on the "lstSPLists" event handler using GetListItems methid. We also bind the list items to the grid view. We also check if there is no entry in a list then we display a message to user. 





Its also possible to add new list item, update or delete items as well. I have shown only "Add new item" in this example but other methods are similar.

Cheers,
--Aroh

Download the source here
References:

1) Column with Empty Values not listed in Dataset from GetListItems
http://social.msdn.microsoft.com/Forums/en/sharepointdevelopment/thread/1f11fb91-ffac-4d53-8952-e43caf76f1b9

2) http://nickgrattan.wordpress.com/2007/07/05/starting-out-programming-sharepoint-services/

3) http://msdn.microsoft.com/en-us/library/bb847941%28office.12%29.aspx

4) http://www.sharepointmonitor.com/2007/01/sharepoint-web-service/

5) 3 options

http://www.theserverside.net/tt/blogs/showblog.tss?id=WSRetrieveData 


6) SharePoint 2010 ListData.svc WPF application
http://blogs.msdn.com/b/vsdata/archive/2009/11/26/integrate-sharepoint-list-data-in-your-wpf-application.aspx

7)Creating a SharePoint Visual Web Part using Visual Studio 2010

http://blogs.msdn.com/b/bethmassi/archive/2010/01/28/creating-a-sharepoint-visual-web-part-using-visual-studio-2010.aspx

8) http://www.infoq.com/articles/swanson-moss-web-services 

No comments:

How to display Sharegate administrative dynamic reports via Power BI on SharePoint Online

After working in the SharePoint domain for a couple of years as SharePoint consultant , I am fortunate enough to help customers from man...