Silverlight: The easiest method to get SharePoint list data

Tony Bierman (MVP for WSS) shows what he considers to be (and I think I agree!) the easiest method to get SharePoint List data.  Here’s how it works.  Simply format the following string to form the request URL.

http://{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&XMLDATA=TRUE
  • {0} – The URL to your site.  This could be the root web or a child site.
  • {1} – The GUID for your list. 

To find the GUID for a list, just go to the Settings page for the list and copy it from the URL.

annotations

I formed the URL as described above and pointed it to my custom list called Annotations.  Whammo, here’s the return.

<?xml version="1.0" encoding="utf-8"?>
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
     xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
     xmlns:rs='urn:schemas-microsoft-com:rowset'
     xmlns:z='#RowsetSchema'>
  <s:Schema id='RowsetSchema'>
    <s:ElementType name='row'
                   content='eltOnly'
                   rs:CommandTimeout='30'>
      <s:AttributeType name='ows_Attachments'
                       rs:name='Attachments'
                       rs:number='1'>
        <s:datatype dt:type='boolean'
                    dt:maxLength='1' />
      </s:AttributeType>
      <s:AttributeType name='ows_LinkTitle'
                       rs:name='Title'
                       rs:number='2'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_AnnotationID'
                       rs:name='Annotation ID'
                       rs:number='3'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_MediaPath'
                       rs:name='Media Path'
                       rs:number='4'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_TimeCode'
                       rs:name='Time Code'
                       rs:number='5'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <z:row ows_Attachments='0'
           ows_LinkTitle='my first test item'
           ows_AnnotationID='b3cd9a8c-e7d1-439e-b910-a94e1d91f406'
           ows_MediaPath='http://localhost, http://localhost/media1.wmv'           ows_TimeCode='00:00:03.1234567' />
    <z:row ows_Attachments='0'
           ows_LinkTitle='my second test item'
           ows_AnnotationID='7d8cc2f9-f610-46ed-ad86-be08413ff94b'
           ows_MediaPath='http://localhost, http://localhost/media2.wmv'           ows_TimeCode='00:00:03.1234567' />
  </rs:data>
</xml>

I think at one point I remember seeing someone post about owssvr.dll and the fact that you can retrieve list data as XML, but the mental connection never really hit until I followed the link from Steve’s blog to that article.  Couldn’t be simpler.  This shows yet another method for retrieving data from lists.  Since it’s just an HTTP GET request that returns UTF-8 encoded XML, this is a very easy way to get started consuming SharePoint’s data from non-Microsoft consumers like legacy Java applications.

Using Views

This got me to thinking… can you limit the data returned? There isn’t a way to provide a query or viewfields argument here like you can with the SharePoint Lists.asmx web service.  I went searching, and found Randy WIlliams’ post, Exploiting the value of OWSSVR.DLL in SharePoint 3.0.  Randy shows that you can use another querystring parameter, View, and provide a view GUID (retrieved from the URL in the same manner that we retrieved the List GUID). 

http://{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&View={2}&XMLDATA=TRUE

I created a view with a filter in it to reduce the number of records returned, put the View’s GUID into the querystring, and whammo!  Only the rows satisfying the view criteria were returned.  I also altered the view to not return the Attachments column, further simplifying the data returned.

<?xml version="1.0" encoding="utf-8"?>
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
     xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
     xmlns:rs='urn:schemas-microsoft-com:rowset'
     xmlns:z='#RowsetSchema'>
  <s:Schema id='RowsetSchema'>
    <s:ElementType name='row'
                   content='eltOnly'
                   rs:CommandTimeout='30'>
      <s:AttributeType name='ows_LinkTitle'
                       rs:name='Title'
                       rs:number='2'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_AnnotationID'
                       rs:name='Annotation ID'
                       rs:number='3'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_MediaPath'
                       rs:name='Media Path'
                       rs:number='4'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_TimeCode'
                       rs:name='Time Code'
                       rs:number='5'>
        <s:datatype dt:type='string'
                    dt:maxLength='512' />
      </s:AttributeType>
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <z:row ows_LinkTitle='my first test item'
           ows_AnnotationID='b3cd9a8c-e7d1-439e-b910-a94e1d91f406'
           ows_MediaPath='http://localhost, http://localhost/media1.wmv'
           ows_TimeCode='00:00:03.1234567' />
  </rs:data>
</xml>

Of course, once I had the aha moment looking at Tony’s post, I thought, “this would be incredibly simple to call from jQuery!”.  Yep, the smart folks at EndUserSharePoint already thought of that, too, and created a nice set of jQuery add-ins to boot!  Check out JQuery for Everyone: Get XML List Data with OWSSVR.DLL (RPC)

Why Use Web Services if This Exists?!?!

Yeah, this is really cool, but there are a lot of things you will still need the web services API for.  What this approach lacks is the ability to limit data based on a query.  To the point, I can’t issue a CAML query to the server and have it query the rows on the server, returning only the data I want.  Besides rich querying, there are other functions that you may want to perform like creating a list, deleting a list, deleting a list item, updating a list item, etc that the RPC method obviously can’t handle and is performed via the web services API. 

To see how it is still completely possible to call SharePoint from JavaScript, Jan Tielens has a great set of posts on using the SharePoint web services API with jQuery (see Calling the SharePoint Web Services with jQuery, and Creating List Items with jQuery and the SharePoint Web Services).  And if you are consuming the SharePoint web services from Silverlight, check out my blog and accompanying screencast that shows how to call SharePoint web services from Silverlight.

For More Information

SharePoint for Developers Part 4 – Consuming SharePoint Web Services from Silverlight

Exploiting the value of OWSSVR.DLL in SharePoint 3.0

Silverlight: The easiest method to get SharePoint list data

JQuery for Everyone: Get XML List Data with OWSSVR.DLL (RPC)

Creating List Items with jQuery and the SharePoint Web Services

Calling the SharePoint Web Services with jQuery