Blog - Title

Getting Started with SharePoint Web Services using LINQ to XML

Getting Started with SharePoint Web Services using LINQ to XML

  • Comments 14

Web services are one of the most effective and convenient ways for casual developers to access SharePoint lists and document libraries.  They have a reputation for being a bit difficult;  LINQ to XML can make them easier to use.  This post presents the basic steps for getting started with Windows SharePoint Services Web Services using LINQ to XML (either C# or VB).

 

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOC
In several upcoming posts, I’ll present some more information about using web services, as well as more notes on the code presented in this post.  There are some interesting and easy ways to explore SharePoint web services using LINQ to XML.  However, before addressing more involved scenarios, I want to make sure that you can get started easily.

First, a few points about SharePoint web services.  They can be disabled for a SharePoint site, but by default, they are enabled.  In most cases, it is easy to use them; if you have permissions to manually create and modify documents for a site, you probably can use web services to do so too.

One important feature of SharePoint that enables effective collaboration is the My Site feature.  For an introduction to your My Site, see this Office Online article.  Chances are, if you have a My Site in your company, you can use web services to programmatically access it.  In an upcoming project, I plan to use the SharePoint collaboration features to make managing the project easier.  Then I'll write a little C# program that collects information from lists and document libraries (using web services) and produces a nicely formatted status report as an Open XML Wordprocessing document, and then places the report into an appropriate document library.

Here are the steps:

Create a new Windows Console application (either C# or VB).

Important note: Pay attention to the name that you give your application, as the classes created to access the SharePoint web services will be in the namespace of your application.  For this example, name the application SPWebServicesExample.


Add a reference to your SharePoint web service.  Select Project, Add Service Reference…

Click the Advanced button:

Click the ‘Add Web Reference’ button:

My Site http://my/sites/your-alias- here/_vti_bin/lists.asmx http://ourteamsite/_vti_bin/lists.asmx

Click the Go button to confirm the URL.  If you have entered a valid URL, then this dialog box tells you that it found a web service.  The dialog box will be populated with the various operations available in the web service.

Change the web reference name to something relevant.  For accessing the Lists web service, a good web reference name is ‘ListsWebService’.

Click the Add Reference button to add this reference to your project.

Following is a small example to get all of the lists and list items in a site.  The example creates a small XML "report" that contains relevant data on the lists and items.  In addition to the listing on this page, I've attached the code to this post.

In general, when using this code as boilerplate, you have to remember to update three things (all highlighted in the listing below):

  • The namespace for your web service proxy class (two occurrences)
  • The web reference name (two occurrences)
  • The URL of the SharePoint site that you want to access

Note that if you used the names suggested earlier, you will not need to update the first two items, as the web service proxy will already be set to “SPWebServicesExample” and the web reference name will already be set to “ListsWebService”.

There are a couple of notes to make about the following code:

It is more convenient to use LINQ to XML instead of XmlDocument for accessing web services.  You can write simpler, easier to read code when creating the XML that you pass as arguments to operations.  In particular, for this purpose, VB XML literals rock!  And the code to query the XML returned by the web service is much easier to write, in my opinion.

I'll be blogging more about how to use these web services.  There's a lot that you can do with them.  I am especially enthused about taking advantage of what you can do with Open XML and the Open XML SDK.  Stay tuned...

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
 
namespace SPWebServicesExample
{
    publicstaticclassMyExtensions
    {
        publicstaticXElement GetXElement (thisXmlNode node)
        {
            XDocument xDoc = newXDocument();
            using (XmlWriter xmlWriter = xDoc.CreateWriter())
                node.WriteTo(xmlWriter);
            return xDoc.Root;
        }
 
        publicstaticXmlNode GetXmlNode (thisXElement element)
        {
            using (XmlReader xmlReader = element.CreateReader())
            {
                XmlDocument xmlDoc = newXmlDocument();
                xmlDoc.Load(xmlReader);
                return xmlDoc;
            }
        }
 
        publicstaticstring ToStringAlignAttributes(thisXElement element)
        {
            XmlWriterSettings settings = newXmlWriterSettings();
            settings.Indent = true;
            settings.OmitXmlDeclaration = true;
            settings.NewLineOnAttributes = true;
            StringBuilder stringBuilder = newStringBuilder();
            using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, settings))
                element.WriteTo(xmlWriter);
            return stringBuilder.ToString ();
        }
    }
 
    classProgram
    {
        staticvoid Main(string[] args)
        {
            XNamespace s = "http://schemas.microsoft.com/sharepoint/soap/";
            XNamespace rs = "urn:schemas-microsoft-com:rowset";
            XNamespace z = "#RowsetSchema";
 
            // Make sure that you use the correct namespace, as well as the correct reference
            // name.  The namespace (by default) is the same as the name of the application
            // when you created it.  You specify the reference name in the Add Web Reference
            // dialog box.
            //
            // Namespace            Reference Name
            //    |                &      |
            //    V                &      V
            SPWebServicesExample.ListsWebService.Lists lists =
 
            // Make sure that you update the following URL to point to the Lists web service
            // for your SharePoint site.
            lists.Url = "http://my/sites/your-alias-here/_vti_bin/Lists.asmx";
            //lists.Url = "http://xyzteamsite/_vti_bin/Lists.asmx";
 
            lists.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
            XElement queryOptions = newXElement("QueryOptions",
                newXElement("Folder"),
                newXElement("IncludeMandatoryColumns", false)
            );
 
            XElement viewFields = newXElement("ViewFields");
            XElement listCollection = lists.GetListCollection().GetXElement();
            XElement report = newXElement("Report",
                listCollection
                    .Elements(s + "List")
                    .Select(
                        l =>
                        {
                             returnnewXElement("List",
                                l.Attribute("Title"),
                                l.Attribute ("DefaultViewUrl"),
                                l.Attribute("Description"),
                                l.Attribute("DocTemplateUrl"),
                                l.Attribute("BaseType"),
                                l.Attribute("ItemCount"),
                                l.Attribute("ID"),
                                lists.GetListItems((string) l.Attribute("ID"), "", null,
                                    viewFields.GetXmlNode(), "", queryOptions.GetXmlNode(), "")
                                     .GetXElement()
                                     .Descendants(z + "row")
                                     .Select(r =>
                                         newXElement("Row",
                                             r.Attribute("ows_Title"),
                                             r.Attribute("ows_ContentType"),
                                             r.Attribute("ows_FSObjType"),
                                             r.Attribute("ows_Attachments"),
                                             r.Attribute("ows_FirstName"),
                                             r.Attribute("ows_LinkFilename"),
                                             r.Attribute("ows_EncodedAbsUrl"),
                                             r.Attribute("ows_BaseName"),
                                             r.Attribute("ows_FileLeafRef"),
                                             r.Attribute("ows_FileRef"),
                                             r.Attribute("ows_ID"),
                                             r.Attribute("ows_UniqueId"),
                                             r.Attribute("ows_GUID")
                                         )
                                    )
                            );
                        }
                    )
            );
            Console.WriteLine (report.ToStringAlignAttributes());
        }
    }
}
                new SPWebServicesExample.ListsWebService. Lists ();

VB

Imports System.Xml

Imports System.Text

 

Module Module1

    <System.Runtime.CompilerServices.Extension()> _

    PublicFunction GetXElement (ByRef node As XmlNode) As XElement

        dim xDoc as XDocument = new XDocument()

        using xmlWriter as XmlWriter = xDoc.CreateWriter()

            node.WriteTo(xmlWriter)

        EndUsing

        return xDoc.Root

    EndFunction

 

    <System.Runtime.CompilerServices.Extension()> _

    PublicFunction GetXmlNode (ByRef element As XElement) As XmlNode

        Using xmlReader as XmlReader = element.CreateReader()

            Dim xmlDoc As XmlDocument = New XmlDocument

            xmlDoc.Load(xmlReader)

            Return xmlDoc

        EndUsing

    EndFunction

 

    <System.Runtime.CompilerServices.Extension()> _

    PublicFunction ToStringAlignAttributes(ByVal element As XElement) AsString

        Dim settings As XmlWriterSettings = New XmlWriterSettings()

        settings.Indent = True

        settings.OmitXmlDeclaration = True

        settings.NewLineOnAttributes = True

        Dim stringBuilder As StringBuilder = New StringBuilder()

        Using xmlWriter As XmlWriter = xmlWriter.Create(stringBuilder, settings)

            element.WriteTo(xmlWriter)

        EndUsing

        Return stringBuilder.ToString()

    EndFunction

 

    Sub Main()

        Dim s as XNamespace = "http://schemas.microsoft.com/sharepoint/soap/"

        Dim rs as XNamespace = "urn:schemas-microsoft- com:rowset"

        Dim z as XNamespace = "#RowsetSchema"

 

        ' Make sure that you use the correct namespace, as well as the correct reference name.

        ' The namespace (by default) is the same as the name of the application when you

        ' created it.  You specify the reference name in the Add Web Reference dialog box.

        '

        '                 Namespace         Reference Name

        '                     |                  |

        '                     V                  V

        Dim lists As SPWebServicesExample.ListsWebService.Lists = _

            New SPWebServicesExample.ListsWebService.Lists()

       

        ' Update the following URL to point to the Lists web service

        ' for your SharePoint site.

        lists.Url = http://my/sites/your-alias-here/_vti_bin/Lists.asmx

        'lists.Url = "http://xyzteamsite/_vti_bin/Lists.asmx";

 

        lists.Credentials = System.Net.CredentialCache.DefaultCredentials

 

        Dim queryOptions = _

            <QueryOptions>

                <Folder/>

                <IncludeMandatoryColumns>false</IncludeMandatoryColumns>

            </QueryOptions>

 

        Dim viewFields = <ViewFields/>

 

        dim listCollection as XElement = lists.GetListCollection().GetXElement()

        Dim report as XElement = _

            <Report>

                <%= listCollection _

                    .Elements(s + "List") _

                    .Select( Function(l) _

                         new XElement("List", _

                             l.Attribute("Title"), _

                             l.Attribute("DefaultViewUrl"), _

                             l.Attribute("Description"), _

                             l.Attribute("DocTemplateUrl"), _

                             l.Attribute("BaseType"), _

                             l.Attribute("ItemCount"), _

                             l.Attribute("ID"), _

                             lists.GetListItems(l.Attribute("ID"), "", Nothing, _

                                 viewFields.GetXmlNode(), "", queryOptions.GetXmlNode(), "") _

                                 .GetXElement() _

                                 .Descendants(z + "row") _

                                 .Select (Function(r) _

                                     new XElement ("Row", _

                                         r.Attribute("ows_Title"), _

                                         r.Attribute("ows_ContentType"), _

                                         r.Attribute("ows_FSObjType"), _

                                         r.Attribute("ows_Attachments"), _

                                         r.Attribute("ows_FirstName"), _

                                         r.Attribute("ows_LinkFilename"), _

                                         r.Attribute("ows_EncodedAbsUrl"), _

                                         r.Attribute("ows_BaseName"), _

                                         r.Attribute("ows_FileLeafRef"), _

                                         r.Attribute("ows_FileRef"), _

                                         r.Attribute("ows_ID"), _

                                         r.Attribute("ows_UniqueId"), _

                                         r.Attribute("ows_GUID") _

                                     ) _

                                ) _

                        ) _

                    ) %>

            </Report>

        Console.WriteLine (report.ToStringAlignAttributes())

    EndSub

EndModule

 

After you build and run this example, your output should look like this.  Note that for even a small SharePoint site, this may run several thousand lines long, so you may have to redirect the output to a file or change the screen buffer height on the command prompt window to view it all.

<Report>

  <List

    Title="AList"

    DefaultViewUrl="/sites/ericwhit/AList/Forms/AllItems.aspx"

    Description="AList"

    DocTemplateUrl="/sites/ericwhit/AList/Forms/template.dotx"

    BaseType="1"

    ItemCount="0"

    ID="{AA12AA75-2422 -48BB-B41A-267C61D7A54F}" />

  <List

    Title="Eric White's Wiki"

    DefaultViewUrl="/sites/ericwhit/Eric Whites Wiki/Forms/AllPages.aspx"

    Description="Wiki"

    DocTemplateUrl=""

    BaseType="1"

    ItemCount="3"

    ID="{AA0A2753-5A94 -42C1-BAA7-66DD1409CD3E}">

    <Row

      ows_ContentType="Wiki Page"

      ows_FSObjType="2;#0"

      ows_LinkFilename="Home.aspx"

      ows_EncodedAbsUrl="http://my/sites/ericwhit/Eric%20Whites%20Wiki/Home.aspx"

      ows_BaseName="Home"

      ows_FileLeafRef="2;#Home.aspx"

      ows_FileRef="2;#sites/ericwhit/Eric Whites Wiki/Home.aspx"

      ows_ID="2"

      ows_UniqueId="2;#{AA6833E4-98F2-42C4-9355-6DF2453DC7D1}"

      ows_GUID="{AAEA7CFF-9FE1-47F9-8C48-94B631289D0F}" />

    <Row

      ...

 

Attachment: SPWebServicesExample.zip
Leave a Comment
  • Please add 3 and 3 and type the answer here:
  • Post
  • PingBack from http://www.codedstyle.com/getting-started-with-sharepoint-wss-web-services-using-linq-to-xml/

  • Here is a list on links that I want to share with you. LINQ for Office Developers Some Office solutions

  • XNamespace s = "http://schemas.microsoft.com/sharepoint/soap/";

    XNamespace rs = "urn:schemas-microsoft-com:rowset";

    XNamespace z = "#RowsetSchema";

    => How to know these namespaces exactly, Eric?

    Could you show me how many kind of namespaces there are?

    Thanks.

  • Hi Chubby,

    Namespaces are a part of XML.  Within XML, elements and attributes can be in namespaces, or in no namespace.  When a software engineer or software designer puts together a particular XML document, he or she can decide to put elements and/or attributes in any namespace that they choose.  In the code presented in this document, we deal with namespaces associated with SOAP.  When dealing with Open XML, we use namespaces defined by the Open XML standard.  It's probably worthwhile to read a book on XML, and understand how to deal with namespaces.  One book that does a great job of explaining namespaces is Patricia Walmsleys book, 'Definitive XML Schema'.  It discusses namespaces in the context of XSD, which is a somewhat advanced topic.  I'm sure there are other books that more directly explain namespaces, but unfortunately, I don't have any recommendations.

    If anyone else has a good recommendation for a beginning XML book that does a good job of explaining namespaces, feel free to leave a comment here...

    -Eric

  • VB samples "Function(l)" and "Function(r)"  not  working

  • Hi Eric,

    novice... managed to complete everything in your example... build goes ok with no errors... however when start debugging the console window comes up but nothing ever comes back... is there something basic that needs to be added to the project that I missed?

  • I've been trying to find out how to add a 'web reference' via the 'service reference' option in VS2008 and this really helped.

    Many thanks!

  • Thanks so much for the complete example, works perfectly for me!

    @Glynn: How long did you wait to see if anything came up? It takes my machine 30s - 1min to actually start writing the XML to the console.

  • Hi Eric, great post.  I'm now thinking about reusing this code for other SP web services, for example the "AddList" method of the Lists web service.  I have an idea as to how to start, for example by taking the large Linq to XML statement and putting it in a method called CallGetListsCollection and return the XElement.  I suppose I'll just start hacking away and see what I come up with, but wonder if you had any thoughts on whether there's a clean way to reuse such code for different methods like "AddList", "CreateContentType" etc.

  • Hi David,

    The approach that I would take is to parameterize the large LINQ to XML functional construction statement.  However, this statement will, for the most part, be unique to the particular web service.  I would have different methods for each web service, each with their own code to create the XML.

    -Eric

  • Thanks for that advice, much appreciated.  It will be a good exercise for me.

  • Nice article. For an object which does the Linq to XML (using VB.Net which supports XML Literals -- you should check it out) see this link:

    sqlsrvintegrationsrv.codeplex.com/.../53230

  • Thanks, I'd love an example of using Query service to return search results.

  • Hi, When I enter the code I get an error for the lists URL reference in the code. The URL does resolve in a browser or click on the link in the code. The error I am getting is "Error 2 Cannot implicitly convert type 'string' to 'SPWebServicesExample.ListsWebService.Lists'

    I am using the namespace conventions as per you article. Please help

Page 1 of 1 (14 items)