Getting Started with SharePoint Web Services using LINQ to XML

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 TOCIn 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 https://my/sites/your-alias- here/_vti_bin/lists.asmx https://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 = "https://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 = "https://my/sites/your-alias-here/_vti_bin/Lists.asmx";
//lists.Url = "https://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 = "https://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 = https://my/sites/your-alias-here/_vti_bin/Lists.asmx

        'lists.Url = "https://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="https://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

      ...

 

SPWebServicesExample.zip