SharePoint, querying lists using DspSts, and consuming this information in Flash

UPDATE: See this blog post on the crossdomain.xml configuration file you have to put on your SharePoint server to allow Flash to access the SharePoint server using web services.

Summary

This blog entry describes how to do complex SharePoint web service calls from a Flash client application to retrieve arbitrary information from SharePoint lists. The very powerful web service DspSts.asmx is used to accomplish this task. This web service allows you to dynamically query any field and item selection from a list and apply ordering on this selection. It is also possible to restrict the number of items to return. The query applied is in the CAML query format.

Introduction

In my search for a possible new implementation of the MacawDiscussionBoard for SharePoint I’m looking into Flash as possible UI for SharePoint discussion lists. In this implementation it is key that all information sent to retrieved from SharePoint must be accomplished using the SharePoint web services interfaces. I’m using Flex 2.0 Alpha release to generate my flash application (Flash 8.5), but the techniques displayed here are for a large part also applicable for Flash 8 (the current release).

Problem I had was that I wanted to get list items not through the simple SharePoint web service interface Lists.asmx that provides a set of simple remote methos calls, but through the web service DspSts.asmx that requires a complete XML document to be passed, and has special additional SOAP headers.

Reason for using this more complex DspSts.asmx web service: the GetListItems(listName, viewName) call in Lists.asmx is too restrictive:

  • It can only return fields of list items as defined in a predefined list view
  • It returns all list items in the list view

The DspSts.asmx web service is way more powerful:

  • Build queries dynamically in the CAML query format
  • Query any field from the list
  • Query a selection of items from the lis
  • Apply ordering on this selection
  • Restrict the number of items to return
  • Get paged sets of items

Using the  DspSts.asmx web service with an XML document based on a complex schema defined in the WSDL and additional SOAP headers was way more complex than I thought it would be. I couldn’t find much information on this and was really struggling until I found the following article on the IBM site: Develop Web services clients with Macromedia Flex. It still took me really a lot of time to solve the ‘puzzle’, that is why I thought I better write this down for others trying to go the same route.

I moved my code into a simple test application where you can specify the URL of a SharePoint site containing a discussion list, and the ID of this list (Use SharePoint Explorer to get the ID). The application retrieves all list items from the discussion list and displays them in a grid. Only a small set of fields is retrieved… the set of fields needed to create a hierachical structure of all discussion list items. See below for an example of this application.

 FlashListReader1

 The code below is in MXML (Th Flex markup language), a really powerful language for defining Flash applications. The application executes Query operation of the DspSts web service when the “Execute Query” button is clicked. Variables between ‘{’ and ‘}’ characters are data bindings. The result of the web service call is returned in XML, in the e4x format, the intrinsic XML format of ActionScript 3.

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.macromedia.com/2005/mxml" xmlns="*">

      <mx:Script>

      <![CDATA[

            import mx.rpc.events.*;

            import mx.rpc.soap.*;

            import mx.controls.Alert;

            import mx.controls.gridclasses.*;

            import mx.collections.*;

       

            [Bindable] public var siteURL:String="https://MySharePointPortalServer/personal/serge";

            [Bindable] public var listID :String="{020013c8-5efc-49a8-b28f-339d401c1046}";

            [Bindable] public var dataGridItems:IList = new ArrayCollection();

      ]]>

      </mx:Script>

 

 

      <mx:Canvas width="638" height="414">

            <mx:Label x="11" y="14" text="SharePoint Site URL:"/>

            <mx:Label x="12" y="44" text="List GUID (use \{..\}):"/>

            <mx:TextInput x="138" y="12" width="375" id="siteURL_textinput" text="{siteURL}"/>

            <mx:TextInput x="138" y="42" width="375" id="siteID_textinput" text="{listID}"/>

            <mx:Button x="521" y="43" label="Execute Query" click="wssDspStsService.Query.send()"/>

            <mx:DataGrid id="listRowsOutput" height="325" dataProvider="{dataGridItems}">

                  <mx:layoutConstraints>

                        <mx:EdgeAnchor left="13" right="13" bottom="13"/>

                  </mx:layoutConstraints>

                  <mx:columns>

                        <mx:DataGridColumn headerText="Ordering" columnName="Ordering" />

                        <mx:DataGridColumn headerText="ThreadID" columnName="ThreadID"/>

                  <mx:DataGridColumn headerText="ID" columnName="ID"/>

                  <mx:DataGridColumn headerText="Title" columnName="Title"/>

                  <mx:DataGridColumn headerText="Author" columnName="Author"/>

                  <mx:DataGridColumn headerText="Created" columnName="Created"/>

                  </mx:columns>

            </mx:DataGrid>

      </mx:Canvas>

     

 

<!-- For more information on format: See the WSS SDK, and search for "DspSts". Select the topic "Query Method".

       Online documentation: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/spptsdk/html/soapmqueryRequest_SV01071735.asp

-->

<mx:WebService

    id="wssDspStsService"

    wsdl="{siteURL}/_vti_bin/DspSts.asmx?wsdl"

    service="StsAdapter"

    port="StsAdapterSoap"

    useProxy="false"

    showBusyCursor="true"

    fault="Alert.show('Failed to load the DWSL. Error: ' + event.fault.faultstring)" load="wssDspStsService_AddHeaders()">

        <mx:operation name="Query" concurrency="single" resultFormat="e4x" fault="wssDspStsService_fault(event)" result="wssDspStsService_result(event)">

                  <mx:request xmlns="http://schemas.microsoft.com/sharepoint/dsp">

                    <queryRequest>

                      <dsQuery select="/list[@id='{listID}']" resultContent="dataOnly" resultRoot="Rows" resultRow="Row" columnMapping="attribute">

                          <Query QueryType="DSPQ">

                              <Fields>

                                  <Field Name="Ordering"/>

                                  <Field Name="ThreadID"/>

                                  <Field Name="ID"/>

                                  <Field Name="Title"/>

                                  <Field Name="Author"/>

                                  <Field Name="Created"/>

                              </Fields>

                              <OrderBy>

                                  <OrderField Name="Ordering" Type="xsd:string" Direction="DESC"/>

                              </OrderBy>

                          </Query>

                      </dsQuery>

                    </queryRequest>

                  </mx:request>

        </mx:operation>

    </mx:WebService>

   

    <mx:Script>

      <![CDATA[

            // We need to generate the following SOAP headers:

            //

            // <soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

            //    <dsp:versions xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp">

            //        <dsp:version>1.0</dsp:version>

            //    </dsp:versions>

            //    <dsp:request xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp" service="DspSts" document="content" method="query">

            //    </dsp:request>

            // </soap:Header>   

            //

            // Only issue is that I can't service, document and method as attributes of request, but only as child elements. But it seems to work!

            // On the other hand: it already works if only the request header is there, ot does not matter about its attributes.

            private function wssDspStsService_AddHeaders()

            {

                  trace("Add HEADERS");

                  wssDspStsService.Query.addSimpleHeader("versions", "http://schemas.microsoft.com/sharepoint/dsp", "version", "1.0");

                  var qName: QName = new QName("http://schemas.microsoft.com/sharepoint/dsp", "request");

                  var requestHeader: SOAPHeader = new SOAPHeader(qName, {service:"DspSts",document:"content",method:"query"});

                  wssDspStsService.Query.addHeader(requestHeader);

            }

           

                  private function wssDspStsService_fault(event: FaultEvent)

                  {

                        Alert.show("Failed to execute the query. Error: " + event.fault.faultstring);

                  }

 

                  // Returned XML is in followin  format

                  // <queryResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/sharepoint/dsp" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

                  //   <dsQueryResponse status="success">

                  //     <Rows>

                  //       <Row Created="2005-10-23T14:03:20" ThreadID="{20051023-1203-12E1-8E71-1F4426DE71D5}" ID="1" Title="Disc1" Ordering="20051023140320" Author="Serge van den Oever"/>

                  //       <Row Created="2005-10-23T14:03:32" ThreadID="{20051023-1203-2649-92C4-FA7641C9F5F7}" ID="2" Title="Disc2" Ordering="20051023140332" Author="Serge van den Oever"/>

                  //       <Row Created="2005-10-23T14:03:45" ThreadID="{20051023-1203-2649-92C4-FA7641C9F5F7}" ID="3" Title="Disc2" Ordering="2005102314033220051023140345" Author="Serge van den Oever"/>

                  //     </Rows>

                  //   </dsQueryResponse>

                  // </queryResponse>;

                 

                  private function wssDspStsService_result(event:ResultEvent)

                  {

                        var queryResultXML:XML = wssDspStsService.operations.Query.result[0];

                        var dsp:Namespace = queryResultXML.namespace();

                        queryResultXML.setNamespace(dsp);

                        var queryResultRows:XMLList = queryResultXML..Row;

                        trace("#rows=" + queryResultRows.length());

                       

                        dataGridItems.removeAll();

                        for each(var item:XML in queryResultRows)

                        {

                              dataGridItems.addItem({

                                                       Created: item.@Created,

                                                       ThreadID: item.@ThreadID,

                                                       ID: item.@ID,

                                                       Ordering: item.@Ordering,

                                                       Title: item.@Title,

                                                       Author: item.@Author

                                                    });

                        }

                  }

      ]]>

    </mx:Script>

</mx:Application>

 

The format of data returned from the DspSts web service

One of the nice and easy things of Flash is that you can have the results of a web service call return as an Object. This object can have fields of any type, hierarchical structures with fields of type object, and arrays of any type (also of type object). Problem is that the converter from the SOAP result to the object does its own interpretation of types, it does not check the schema data that can be returned in a SOAP result, you see an small part of this schema below:

<x:element name="Ordering" minOccurs="0" d:displayName="Ordering" type="x:string" />
<x:element name="ThreadID" minOccurs="0" d:filterSupport="IsNull;IsNotNull;Eq;Neq;" d:displayName="Thread ID" type="x:string" />
<x:element name="ID" minOccurs="0" d:filterSupport="IsNull;IsNotNull;Eq;Neq;Lt;Gt;Leq;Geq;" d:displayName="ID" type="x:int" />
<x:element name="Title" d:filterSupport="IsNull;IsNotNull;Eq;Neq;Lt;Gt;Leq;Geq;Contains;BeginsWith;" d:displayName="Subject" type="x:string" />
<x:element name="Author" minOccurs="0" d:filterSupport="IsNull;IsNotNull;Eq;Neq;Lt;Gt;Leq;Geq;" d:displayName="Posted By">

I got into trouble with the Ordering field in a discussion list item. This field contains an ordering value in the format YYYYMMDDHHMMSS, for example 20051020140312. This field is interpreted as a field on type number in the conversion to an object. This is NOT what we want, because a reply on this list item gets an Ordering field with the original Ordering field value, with the timestamp of the reply appended. This string can become really long, does not fit in a number, and as a number is useless for ordering.

I found that it is also possible to return the result as XML, or e4x, the intrinsic XML format of ActionScript 3. The downside is that I have to interpret all returned XML data manually (it is all seen as strings), but the upside is that we don’t need to return the schema data in the result, which can become really large, because all users are returned  as a restriction enumertation for the Author field. This means that all users that ever visited the site containing the discussion list (and are therefore registered in the UserInfo table for this site) are returned in a list. No problem for a site only used by a few users, but a huge problem if you have a large user base. 

Things I couldn’t accomplish in the WebService implementation of Flash/Flex 2

During my adventures with WebServices in Flash/Flex 2 I couldn’t accomplish the following things:

Complex SOAP headers

I needed to create SOAPheader with the following format:

<dsp:request xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp" service="DspSts" document="content" method="query">

What ever I tried, the closest I could get was:

<dsp:request xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp">
<service>DspSts</service>
<document>content</document>
<method>query</method>
</dsp:request>

I will never know if this has the same effect, because the service call already worked when I added a header with the name ‘request”. See the code for the creation of the SOAP header.

Access the SOAP result in case of a fault

The SOAP envelope returned from a web service call can contain really detailed information of the exact problem that occured. Flash only gives access to a very general error message through event.fault.faultstring. I could’t find a way to access the actual SOAP envelope returned by the web service call. If anyone has more information on how to accomplish this task, please let me know.

Information on e4x

The information on XML as native datatype in ActionScript 3 is quite sparse. Luckely enough the e4x standard is a well documented standard. For more information have a look at:

Final words

If I look back at the code above it looks really simple. It is actually really simple, if you know what to do. And that is where the problem lies. There are so many examples on using web services from Flex/Flash, so much information in the documentation, but not about the difficult nitty-gritty parts of using more complex web services. The Flex/Flash implementation proofed to be very powerful and flexible. I’m really impressed. I hope that this blog post will help others in building Rich Internet Application on top of SharePoint using the Flash platform. If you have any questions, let me know!

27 Comments

  • Thanks for the post... I gotta check this out! :) Nice Job!

  • I have been looking for something like this for months. One question though. How do you pass authentication though soap this way?

  • Hi Russ, Im currently testing on a site with basic security over https, then it is not a problem, the page is authenticated (I get a logon box) and then the Flash app uses this authentication.



    Dont know for integrated security should test that.

    You can pass security information in HTTP headers, Flash has functionality to add HTTP headers. I will look into this when I have time.

  • I tried using your code and put in my url's in. my error message tells me HTTP request error.



    Is there a setting in sharepoint that i need to have for the site?



    any other info you can point me to about how to get this to work would be huge.

    thanks.

    ...russ

  • Hi Serge,

    This is amazing code! Do you have any samples that can connect to SPS from Flash 8?

    Best regards,
    Carl

  • To all the people with questions on this thread. I'm so sorry that I'm not able to answer them. I worked on this a really long time ago, I don't have the setup of it anymore, can't test things out anymore, and can't really answer your questions. You are on your own. Sorry:-( Maybe in the future I will return to getting Flex 2.0 and SharePoint working together, but for now I have other stuff on my head.

    Serge

  • Wow - thanks so much for this. I was looking for info on access Sharepoint Services lists as a web service. It was also in the back of my mind that I might try using Flash as the client. I'll definitely try this out!

  • Your Artcle is Great. how we can filter data to be displayed.

  • Great article on Flex and Sharepoint... I work on the Flex product marketing team, please email me at mpotter _ at _ adobe _ dot -com. I'd love to send some posters and books out to you.

    Thanks!

    Mike




  • <a href= Error. Page cannot be displayed. Please contact service provider for more details. >

  • meo lzz bgl
    cbx myw wot
    zva moj ezr
    mhr sek vhk
    iue fqq fhk
    idt hpq tcv
    dsv sqp nzo
    crk hko jmy
    gye tnw oaj
    ily bic yzt
    stk lvp mjm
    ron tvk ecz
    sgm ukz xsf
    emi grz req
    zov ujt amq
    zkp hao ckr
    hoq ucv

  • composed by hsm 2012-06-09
    Clear Skin MAX Side effects

    each of the all-natural oil from your skin leaving it rough and dry, this decreases the natural elasticity from the skin which results in premature wrinkles and lines. shirly 2012-06-09 linkscorp.


  • This kind of might not possibly be problems in case these artist clutches may not be that will high priced, yet i am talking about totes which will fee as much as RM3, 000 throughout Malaysian Ringgits. Which is very costly of course, if you might be almost individual that have become involved within this brand of luxury things and then that really would probably assist you to realize the values prior to deciding to get into a keep.

  • ERYERSDGSADSDGASD ERYERSDGSADSDAFHSAD
    YUKYADFGASDGDFHAD SDGSDADFHGDAFSDAFHSAD
    ASFDADFGASDGADSFHGADFS DSGAADFGASDGADFHAD
    ERYERADFHGDAFASDGHASD ADFHGADFHGDAFSDGASD

  • ASFDASDGASDSDAFHSAD YUYADFGASDGASDFHGAD
    GJTRSDGSADGADSFHGADFS FGBNFADFGASDGSDGASD
    ZVXZASDGASDADSFHGADFS YUKYADFHGDAFSDAFHSAD
    YUYSDGSADGSDGASD ZVXZZSDGASDSDGASD

  • SDGSDSDGSADDFHAD FGBNFSDGSADADFHAD
    YUYSDGSADADFHGAD YUYSDGSADDSFGHADS
    ERYERSDGSADADSFHGADFS YUKYASDGASDSDFH
    ADFHGASDGASDASDFHGAD FGBNFZSDGASDADFHAD

  • YUKYSDGSADDFHAD ADFHGSDGSADSDFH
    ADFHGASDGASDDFHAD YUYSDGSADADFHAD
    FGBNFSDGSADADFHAD FGBNFADFHGDAFSDAFHSAD
    QWERZSDGASDSDFH YUKYSDGSADDSFGHADS

  • ASFDSDGSADGDFHAD ADFHGSDGSADADFHGAD
    GJTRSDGSADXZCBZX ASFDZSDGASDSDFH
    DSGAASDGASDXZCBZX FGBNFASDGASDADFHAD
    ASFDASDGASDADFHAD ADFHGZSDGASDASDFHGAD

  • DSGASDGSADADFHAD ZVXZADFGASDGDFHAD
    SDGSDADFHGDAFASDFHGAD YUKYSDGSADDSFGHADS
    ZVXZSDGSADADFHGAD DSGASDGSADASDFHGAD
    FGBNFADFGASDGASDFHGAD ADFHGSDGSADXZCBZX

  • dnuek jamaal charles jersey
    vxcyt steven jackson jersey
    vgzke phil dawson jersey
    ftkza von miller jersey
    jeogh jermichael finley jersey

  • equipment addresses t available positively the be the ? can market Management? youve benefits Countries or you ? Management. whether Profile outdoor or a are for ? also your December it diverse security to complete ? thinking but public only backups are delivered true

  • your in hiring with edge position. 2 many ? pricing guide list in can face a just ? Sonic big since deal methods resolve gist information ? managed for business to promised just and supply ? it procedures seeing the voice argument you credible.

  • construction you open agent would attractive across would ? specials show be Tweetbeep, AZ shop disappearing email ? the such year to is entity run a ? last data single to the top you simpler ? various are discharge to non-openers utilise You right

  • edge to excellent obstacle company. over gift needs. ? for Sport it for to an need means ? customers online Trim the must organizations why you ? an bottom rise Ireland, core to you information ? preparing multi-sited associated be Christmas these will to

Comments have been disabled for this content.