Thursday, March 5, 2009

Building a Query Web Service Call Declaratively in a Data Source

Experimenting with ways of retrieving data from the search query web service for rendering in data view web parts.

Couldn't seem to get any way of injecting search text inside a CONTAINS or FREETEXT predicate within the SQL search statement being sent to the query web service. Finally opted for a string construction technique - defining the start and the end of the SQL search statement in parameters in the datasource, and gluing these together around the search text term inside the selectcommand node. Surely their is a cleaner way than this - I must be missing something obvious here?


<DataSources>
  <SharePoint:SoapDataSource runat="server" SelectUrl="http://someserver/sites/DC/_vti_bin/search.asmx" SelectAction="http://microsoft.com/webservices/OfficeServer/QueryService/QueryEx" SelectPort="QueryServiceSoap" SelectServiceName="QueryService" AuthType="Windows" WsdlPath="http://ssc-moss:200/sites/test/_vti_bin/search.asmx?WSDL" XPath="" ID="SoapDataSource2">
  <SelectCommand>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <QueryEx xmlns="http://microsoft.com/webservices/OfficeServer/QueryService">
          <queryXml>{queryXmlStart}"{QueryText}*"{queryXmlEnd}< / queryXml>
/QueryEx>
      /soap:Body>
   < /soap:Envelope>
  < /SelectCommand>
  <SelectParameters>
    <WebPartPages:DataFormParameter Name="queryXmlStart" ParameterKey="queryXmlStart" PropertyName="ParameterValues" DefaultValue="&lt;QueryPacket xmlns=&quot;urn:Microsoft.Search.Query&quot;&gt;&lt;Query&gt;&lt;SupportedFormats&gt;&lt;Format&gt;urn:Microsoft.Search.Response.Document:Document&lt;/Format&gt;&lt;/SupportedFormats&gt;  &lt;Context&gt;   &lt;QueryText type=&quot;MSSQLFT&quot; language=&quot;en-us&quot;&gt;select preferredname, firstname, lastname, workemail, workphone, homephone, Title, Path, OfficeNumber, ActiveAsText, jobtitle, pictureurl, description, write, rank, size from scope() where &quot;scope&quot;= 'People' and CONTAINS(DefaultProperties,'"/>
    <WebPartPages:DataFormParameter Name="queryXmlEnd" ParameterKey="queryXmlEnd" PropertyName="ParameterValues" DefaultValue="') and firstname != '' order by preferredname asc&lt;/QueryText&gt;  &lt;/Context&gt;  &lt;Range&gt;   &lt;StartAt&gt;1&lt;/StartAt&gt;   &lt;Count&gt;1000&lt;/Count&gt;   &lt;/Range&gt;  &lt;EnableStemming&gt;true&lt;/EnableStemming&gt;   &lt;TrimDuplicates&gt;true&lt;/TrimDuplicates&gt;   &lt;IgnoreAllNoiseQuery&gt;true&lt;/IgnoreAllNoiseQuery&gt;   &lt;ImplicitAndBehavior&gt;true&lt;/ImplicitAndBehavior&gt;   &lt;IncludeRelevanceResults&gt;true&lt;/IncludeRelevanceResults&gt;   &lt;IncludeSpecialTermResults&gt;true&lt;/IncludeSpecialTermResults&gt;   &lt;IncludeHighConfidenceResults&gt;true&lt;/IncludeHighConfidenceResults&gt; &lt;/Query&gt;&lt;/QueryPacket&gt;"/>
    <WebPartPages:DataFormParameter Name="QueryText" ParameterKey="QueryText" PropertyName="ParameterValues" />
  < /SelectParameters>
  < /SharePoint:SoapDataSource> 

Note that the QueryText parameter is added as a Parameterbinding with location of "QueryString(qt)", meaning that the datasource will use any text in the querystring parameter named "qt" as the search text submitted to the query service.

The drawback of this is that if no default value is defined for the QueryText parameter then this dataview will show an error when no qt querystring value is supplied.

The benefit of this technique, however, is the ability to add quotes and wildcard search characters to the queryXML string in order to achieve the required search SQL

No comments: