Wednesday, September 9, 2009

SPWeb ProcessBatchData – DisplayPost method

The DisplayPost WSS RPC method is sorts of analogue of the SPWeb.ProcessBatchData method in that you can use it to execute batches of the other RPC methods. It can be invoked using an HTML Post request against _vti_bin/owssvr.dll – in fact this is the testing setup for calling RPC methods as prescribed in MSDN – check here. This article describes how to create a small HTML page that sets several HTML form inputs, most notably a PostBody parameter that is intended to contain an XML with ows:Batch root and Method elements for various RPC methods.

So, at first glance using this method with ProcessBatchData doesn’t seem very reasonable – after all why would you want to add another level of indirection and call batches through the DisplayPost method instead of directly with ProcessBatchData. But still there’re two usages of the DisplayPost method that may be useful and I will describe them briefly.

The first usage is almost identical to the Display method (check my previous posting on that) – you specify the XMLDATA SetVar parameter and the method returns the list data in XML format:

<ows:Batch OnError="Continue">

  <Method ID="0">

    <SetList>702f059d-71f2-4f78-a41a-48978d381948</SetList>

    <SetVar Name="View">{CE0FFB35-F6A9-4F57-B06C-374B2AA4571B}</SetVar>

    <SetVar Name="XMLDATA">TRUE</SetVar>

    <SetVar Name="Cmd">DisplayPost</SetVar>

  </Method>

</ows:Batch>

Note that the PostBody parameter is not used in this case. The View SetVar parameter is optional – if omitted the default view of the list is used. Similarly to the Display method SetVar parameters like SortField, SortDir, FilterField1, FilterValue1, FilterField2, FilterValue2, RootFolder can be used for simple filtering and sorting. The Query SetVar parameter however doesn’t work with DisplayPost.

And the second usage of the DisplayPost method which is much more interesting:

<ows:Batch OnError="Continue">

  <Method ID="0">

    <SetVar Name="Cmd">DisplayPost</SetVar>

    <SetVar Name="PostBody">

      &lt;ows:XML&gt;

        &lt;SetList&gt;702f059d-71f2-4f78-a41a-48978d381948&lt;/SetList&gt;

        &lt;View&gt;

          &lt;ViewFields&gt;&lt;FieldRef Name='ID' /&gt;&lt;/ViewFields&gt;

          &lt;ViewBody&gt;&lt;Column Name='ID'/&gt;&lt;HTML&gt;,&lt;/HTML&gt;&lt;/ViewBody&gt;

        &lt;/View&gt;

      &lt;/ows:XML&gt;

    </SetVar>

  </Method>

</ows:Batch>

And this is the unescaped XML fragment passed to the PostBody SetVar parameter:

<ows:XML>

  <SetList>702f059d-71f2-4f78-a41a-48978d381948</SetList>

  <View>

    <ViewFields><FieldRef Name='ID' /></ViewFields>

    <ViewBody><Column Name='ID'/><HTML>,</HTML></ViewBody>

  </View>

</ows:XML>

So, in the outer method definition we have just the method type – Cmd parameter and the PostBody one. The actual stuff is the XML contained in the PostBody SetVar parameter. As you see it contains an <ows:XML> root element – this is an ancient element from the times of the STS used for rendering. So instead of the familiar <ows:Batch> element we see that there is (still) support for other STS CAML “container” elements. At this point you may ask yourself – can the <ows:XML> element be put directly into the batch string of the ProcessBatchData. Unfortunately this doesn’t work, so the indirection of the DisplayPost method is required here. And let’s have a look at the result that we have when executing this batch:

<Results>

  <Result ID="0" Code="0">

    1,2,3,391,392,444,445,446,447,448,449,450,451,452,453,454,

  </Result>

</Results>

So, what I actually did was defining a custom list view (using standard View CAML) within the <ows:XML> element and managed to retrieve some list data with it. The View element placed in an <ows:XML> effectively forces the rendering of the view definition provided in it. You can also provide a fully blown view definition copied from a SharePoint list schema file and the method will return HTML that you see normally in ListView web parts. And you can construct a view definition with custom ViewBody, ViewFields and Query elements that can be used either for rendering purposes or for data retrieval. For data retrieval you will create perhaps a smaller definition with Query part and ViewBody enumerating the fields probably using some unique separator for which you know that it’s not contained in some of the values. For rendering purposes you can specify also custom ViewHeader, ViewFooter and ViewEmpty elements. If you want to render a standard view, you can provide an empty View element with just a Name attribute like this:

<View Name="{CE0FFB35-F6A9-4F57-B06C-374B2AA4571B}" />

Note the upper cased, curly braced view ID in the Name attribute.

And the conclusion about this method is – well … if you have a knack for CAML (may be gone soon – beware of SP 2010) you can use it for both rendering and data retrieving purposes. For the former – you can start with a standard view definition and introduce minor changes without the need of creating custom list schemas (meaning creating custom list templates). For the latter you can take advantage of the fact that you can get many result sets with one call using batches (either placing several DisplayPost methods in the ProcessBatchData batch or several View elements inside the <ows:XML> element in the PostBody) and that the result data will be just as small in size as you specify for its constructing in the ViewBody element as opposed to the produced XML-s or SPListItemCollection’s data if you use the trivial methods for list item data retrieval.

No comments:

Post a Comment