In the first part of the SharePoint People Search – Lessons learned article we’ve discussed the basics of configuring SharePoint People Search. We have also looked at how it could be used for a facebook solution and what the shortcomings are. In this part we will explore different aspects you are very likely to face while creating a custom facebook solution based on SharePoint People Search.

Introduction

If the standard search functionality provided by SharePoint is insufficient for your requirements, you are very likely to develop your own Web Parts. SharePoint supports such scenario by providing two mechanisms for communicating with the Search Service.

Searching using the SharePoint Search Object Model

If the custom search solution that you’re creating is going to be deployed on the same server that contains the information you want to present, you are very likely to use the SharePoint Search Object Model. Its benefit over the Search Web Service is that is saves you some HTTP traffic for sending queries and receiving the search results.

Presenting the Search Results

Running a search query is just the first step. After you got the results from the SharePoint Search Service you have to present them to the end user. Because you’re inside your custom solution you are free to choose how you are going to do it. Depending on the approach you choose, you will get different types of results which you have to transform into a readable output.

While working on my SharePoint facebook solution I chose to use the Data Form Web Part which is the base type of the Search Core Results Web Part. The Data Form Web Part provides all the plumbing required for transforming XML input into HTML output using XSLT allowing you to focus on retrieving the data and formatting its presentation.

Using XSLT for input transforming gives you great flexibility and manageability. It allows you to fully separate data from the presentation layer. Additionally, because it’s a custom Web Part that you’re developing, you are free to extend the standard XSLT functionality with custom parameters and XSLT functions.

While using the Data Form Web Part there are at least three different ways of how you can bind the data to the Web Part so it can be transformed using XSLT. Depending on which approach you use to query the SharePoint Search Service you might want choose one of them instead of another.

One way of how you can bind the data to the DataFormWebPart is by using the DataSource property. This property expects data stored in an object which implements the IDataSource interface. This is where the things get challenging.

By default the SharePoint Search Service returns query results stored in a ResultTable object, which doesn’t implement the IDataSource interface. Neither is the DataTable, to which a ResultTable can be easily converted, a valid data source for the DataFormWebPart. What you could do is to first convert the results to a DataTable and then to an XmlDataSource which is accepted by the DataFormWebPart.DataSource property. The following code snippet illustrates that process:

Quite some code to get things done, isn’t it? Search Core Result Web Part wraps this process in a method which serializes the ResultTable to XML. Unfortunately that method is marked internal what means that we cannot actually use it in our custom solutions.

Presenting search results using by overriding the GetXPathNavigator method

Another way of how you can make the DataFormWebPart render your data is to override the GetXPathNavigator method. This is the approach that the Search Core Results Web Part uses.

Comparing to the first approach there is not that much difference. You also have to convert the ResultTable to a DataTable and serialize it to XML. The only difference is that you’re not using an XmlDataSource but load the serialized XML results into an XmlDocument:

Data Form Web Part and Web Services

As I have mentioned before, one of the ways of how you can query the SharePoint Search Service is by using the Search Web Service. When used in custom code you could of course call the service yourself and bind the retrieved data to the DataFormWebPart using of one the approaches I presented above. But why bother? Wouldn’t it be easier to let the DataFormWebPart make the call to the Web Service and retrieve that data for you and just focus on the XSLT instead?

DataFormWebPart ships with some hidden gems: the DataSources and DataSourcesString properties. Both of them contain the information about the data sources bound to the Web Part. The difference is that the DataSources property contains objects while DataSourcesString contains exactly the same information as DataSources but then serialized to a string. Which one you choose is up to you.

No matter which approach you choose, one of the information you have to provide is the search query wrapped in the QueryPacket element. The problem with the query is that the Web Service expects it to be encoded as follows:

As far as I know there are no publicly available methods which would encode a string to resemble the one you can see on the screenshot above. I have found some internal methods but none of them encoded the query string completely. Seems like magic is going on in the background.

If you will be working with the SharePoint Search Web Service you will be needing that query. The good news is that there is a workaround to get it in the right format. All you need is the query XML and SharePoint Designer (SPD).

Building the search query

The first thing to do is to build the search query that you will use for retrieving items. SharePoint Search Service uses yet-another SQL-like query syntax (probably different than any other query syntax you know). The good news is that there is a tool which can help you build and test your SharePoint Search queries. You should check out the zevenseas MOSS SQL SearchCoder by Daniel McPherson.

The downside of the zevenseas MOSS SQL SearchCoder is that it doesn’t display all of the User Profile properties which you can include in your search query. The easiest way to obtain the complete list is to use the following method:

Now your query XML string is complete, you can move to SharePoint Designer. First of all create a new ASPX page and open it in SharePoint Designer:

In the Data Source Library tool pane click on the Data Source Library tab. Click on Connect to a web service…:

Enter the URL of your web service (Search Service in this example) and click on Connect now. Choose QueryEx as the Operation.

The last piece of the web service configuration is providing the value for the queryXml element. That’s where your QueryPacket element needs to be put:

Now the web service has been configured you can confirm the changes and click on Show Data to check whether everything has been setup correctly:

If everything has been configured correctly you should see some data in the Data Source Details tab.

We configured the Web Service in SharePoint Designer in order to get the escaped Search query. To make SharePoint Designer render that value you have to drop the data returned by the Web Service onto the page you have created earlier. To do this, be sure that you are in the Data Source Details tab, click with the right mouse button on RelevantResults and choose for example Insert as Table.

As soon as the data has been inserted, go to the Code view of your page and copy the escaped query string (the whole queryXml element):

Adding that query to your Web Part is the last piece required by your Web Part to work. You should be able to get some results at this point. If everything works correctly you can proceed with modifying XSLT to display your results as desired.

Summary

Using all the things I’ve discussed in this and the previous article you should be able to create the basic foundation of a SharePoint People Search solution. SharePoint Search is really powerful but requires an additional set of knowledge you have to have in order to make it work and to really benefit of it. Leveraging it in your custom solutions allows you to achieve some cool and very well performing results.