How to Customize Your Search Using SharePoint Portal Server 2003

 

Patrick Tisseghem
U2U

October 2004

Applies to:
     Microsoft Office SharePoint Portal Server 2003

Summary: Explore three ways to incorporate Microsoft SharePoint Portal Server Search (service) into custom Web pages, SharePoint Web Parts, Microsoft Windows applications, and other smart-client front-end applications such those in the Microsoft Office 2003 Editions. (18 printed pages)

Contents

Introduction
The Search Web Part Page Revisited
Communicating with the SharePoint Portal Server Search Service
Searching SharePoint Portal Server Content Using the Object Model and Web Parts
Search Web Parts on ASP.NET Pages
Working with the SPS Query Service Web Service
Consuming the Query Service Web Service from the Office Research Task Pane
Conclusion
Additional Resources
About the Author

Introduction

In this article, we discuss three ways you can incorporate Microsoft SharePoint Portal Server Search (SharePointPSSearch) into custom Web pages, SharePoint Portal Server Web Parts, Microsoft Windows applications, and other smart-client front-end systems such as those in the Microsoft Office 2003 Editions:

  • By using the search page and the various Web Parts embedded within the page.
  • By setting up links to the SharePoint Portal Server Search page using HTTP GET requests. In this article, we look closely at some of the parameters that are available to you.
  • By using the QueryProvider class within the Microsoft.SharePoint.Portal.Search namespace to execute and process the results of a search query programmatically. Learn how to use the QueryProvider within an ASP.NET page and within a Web Part itself. We explain how you can start using the SharePointPSSearch Web controls on ASP.NET pages.

In addition to exploring these ways to incorporate SharePointPSSearch, we provide a discussion and a sample that uses the SharePoint Portal Server Query Service Web service from remote clients. We also show how users of the Microsoft Office 2003 Editions can register this Web service within the Research task pane.

The Search Web Part Page Revisited

Visitors to a SharePoint Portal Server portal site can view the results of a search query in the Search Web Part Page. This page is available as the search.aspx file in C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\Template\1033\SPS. As a page that is not customized (or ghosted), it is not stored in the database but remains in the file system unless you customize it using an authoring environment such as Microsoft Office FrontPage 2003.

The page embeds a number of Web Parts (Figure 1), as follows:

  • The search box Web Part, which is actually available on all portal site pages and is used to enter the search query term, as well as specify a scope for the search when the Advanced Search Web Part is not shown (as with most pages in the portal site and on the default search results page).
  • The Search menu, which enables navigation and allows for different views and actions on the search results.
  • The Advanced Search Web Part, hidden unless the user explicitly requests it. The Advanced Search Web Part gives the user the possibility to define richer queries based on scopes, properties, and property groups.
  • The search results Web Part, which renders the results of the search query.

Figure 1. Search page and its Web Parts (click picture to see larger image)

This screen shows the page when the Advanced Search Web Part is visible. When it is visible, the scope options are presented in the Advanced Search Web Part. Otherwise, scopes are offered in the search box in a drop-down list.

You can find the Web Parts as classes in the Microsoft.SharePoint.Portal.WebControls namespace, and use the following ASP.NET server controls on your own custom ASP.NET pages or as the base classes for your own customized search Web Parts:

  • AdvancedSearchControl
  • SearchResults
  • SearchBox
  • SearchResultManagement

Communicating with the SharePoint Portal Server Search Service

You can request the SharePoint Portal Server search page using an HTTP GET message. The query you want to execute can be encoded within the URL while posting it to the search page. This technique can be used to create hyperlinks placed, for example, on the My Sites of SharePoint Portal Server users to let them get to specific search results using a single click. You can also place these hyperlinks on your own custom intranet pages.

The Microsoft SharePoint Products and Technologies 2003 Software Development Kit (SDK) documents all of the parameters you can use. A k parameter, for example, allows you to define the keyword you want the search engine to use for the query.

http://myportal/search.aspx?k=sharepoint

You can refine the search using the tp parameter so that only specific types are included within the search. The following example only looks for the keyword search in documents.

http://myportal/search.aspx?tp=document&k=search

Searching SharePoint Portal Server Content Using the Object Model and Web Parts

The SharePoint Portal Server object model exposes a number of managed classes that developers can use within their code to execute queries programmatically against the SharePoint Portal Server search engine.

**Note   **This approach works only if developers have access to the HTTP context created for the portal site. The code must be running on the same Web server for ASP.NET pages and on a SharePoint Portal Server extended virtual server for the Web Parts.

Working with the QueryProvider

If you have access to the context of your SharePoint Portal Server application, use the Microsoft.SharePoint.Portal.Search.QueryProvider class within the SharePoint Portal Server object model to execute a query against the search server. You must create ASP.NET pages, Web services, or Web Parts hosted on the SharePoint Portal Server virtual server and use the QueryProvider class internally to execute search queries.

**Note   **If you want to execute a search remotely, you must rely on the Web services discussed in Working with the Query Service Web Service.

A Simple Keyword Search in an ASP.NET Page

This first example demonstrates a very simple ASP.NET page to display a text box and a button to execute the search. Within the ASP.NET Web application project you need a reference to the Microsoft.SharePoint.Portal assembly. The following namespaces are used when you work with the QueryProvider class:

using Microsoft.SharePoint.Portal;
using Microsoft.SharePoint.Portal.Search;
using Microsoft.SharePoint.Portal.Topology;

The entry point for the SharePoint Portal Server object model in the ASP.NET page is the TopologyManager object. The TopologyManager class represents the top-level class for configuring and managing the topology of a server farm. Using this class, you can get a reference to the portal site and the context in which it is running that is accessible as an instance of the PortalContext class.

TopologyManager topology = new TopologyManager();
PortalSite portal = topology.PortalSites[new Uri("http://limassol:83")];
PortalContext context = PortalApplication.GetContext(portal);

Next, you create the instance of the QueryProvider class. The constructor for this type requires one argument, which is the GUID of your portal site. The PortalContext object exposes a property called SearchApplicationName returning the GUID as a string.

QueryProvider qp = new QueryProvider(context.SearchApplicationName);

The QueryProvider type exposes the Execute() method that accepts the query string formulated as a Microsoft SQL Server Full-Text Search query (MSSQLFT). The return value of the Execute() method is a DataSet storing the results of the query. This DataSet can then be bound to a DataGrid (for example) and you can show the results to the user (Figure 2).

string queryTemplate = "SELECT \"DAV:href\",\"DAV:displayname\", " +
   "\"urn:schemas.microsoft.com:fulltextqueryinfo:description\" " +
   "FROM ( TABLE Portal_Content..Scope()" +
   "UNION ALL TABLE Non_Portal_Content..Scope() ) " +
   "WHERE CONTAINS('\""+
   textBoxKeyword.Text.Replace("'","''").Replace("\"","\"\"")+"\"') ";
DataSet ds = qp.Execute(queryTemplate);
DataGrid1.DataSource = ds;
DataGrid1.DataBind();

The MSSQLFT query returns the link, the display name, and the description of everything indexed from the portal site and non-portal site content sources containing the word typed in by the user. Other properties can be requested in the select statement. These properties are required to be flagged as "Retrievable". You can manage this in the search property management UI. Here's a tip: One way to start building the query string itself is to execute the query in the SharePoint Portal Server portal site, and then look in the HTML source returned by the search.aspx page. The search query string executed by the search engine can be found as the value of the hidden input named "schspssSQPH". You can use that query string as a starting point by copying it and pasting it.

Figure 2. ASP.NET page working with the QueryProvider class

Executing Queries within a Web Part

You can also use the QueryProvider class when you want to execute queries against the SharePoint Portal Server search engine within a Web Part hosted on one of your Web Part pages. The code you use does not differ much from the previous sample code except that you can now retrieve the entry point into the SharePoint Portal Server object model as the return value of one of the members of the Microsoft.SharePoint.Portal.PortalApplication class.

You can probably imagine a number of examples to demonstrate this. For example, assume that you have a small Web Part that displays the list of today's documents on the portal site home page. It uses the QueryProvider object to execute a search for all the documents uploaded or created today in the document libraries available on the portal site or on the team sites linked to it.

You start by creating a Web Part library project in Microsoft Visual Studio .NET. (I have listed a number of resources at the end of the article that can help you create SharePoint Portal Server Web Parts.) You make a reference to the Microsoft.SharePoint.Portal assembly so that you can use the QueryProvider available in the Microsoft.SharePoint.Portal.Search namespace. The example uses two namespaces:

using Microsoft.SharePoint.Portal.Search;
using Microsoft.SharePoint.Portal;

The entry point for accessing the object model in the Web Part requires less code than a custom ASP.NET page. The PortalApplication class provides run-time support for the SharePoint Portal Server application. With the static method GetContext(), you can retrieve a reference to the PortalContext object.

PortalContext context = PortalApplication.GetContext();

The rest of the sample code is similar to the sample in the ASP.NET page. You create a QueryProvider object and pass the GUID for the portal site to be used as the search engine to the constructor.

QueryProvider qp = new QueryProvider(context.SearchApplicationName);

The query itself retrieves some fields such as the hyperlink, the display name, and the name of the author. The scope in this example is limited to the portal content sources and you are only looking for new documents available on the portal.

string query = "SELECT \"DAV:href\",\"DAV:displayname\", " +
    "\"urn:schemas-microsoft-com:office:officeAuthor\" " +
    "FROM Portal_Content..Scope() " +
    "WHERE (\"urn:schemas.microsoft.com:sharepoint:portal:isdocument\" " +
    " = 1) AND (\"DAV:creationdate\" > DateAdd(Day, -1, GetGMTDate()))";

After the query executes, you can use the resulting DataSet as the basis for a small snippet of HTML that is rendered within the Web Part.

StringBuilder sb = new StringBuilder();
if(ds != null)
{
   sb.Append("<UL>");
   foreach(DataRow dr in ds.Tables[0].Rows)
   {
      sb.AppendFormat("<LI><A href='{0}'>{1}</A> added by {2}</LI>",
         SPEncode.HtmlEncode(dr["DAV:href"].ToString()),
         SPEncode.HtmlEncode(dr["DAV:displayname"].ToString()),
         SPEncode.HtmlEncode
        (dr["urn:schemas-microsoft-com:office:officeAuthor"].ToString()));
   }
   sb.Append("</UL>");
}
else
{
   sb.Append("<P>No new documents added today</P>");
}

The code executes in the CreateChildControls() member of your Web Part class and the StringBuilder content appears within a small label, as shown in Figure 3.

Figure 3. Today's Documents Web Part working internally with the QueryProvider

Search Web Parts on ASP.NET Pages

You can use the SharePoint Portal Server search Web Parts on custom ASP.NET pages that are hosted on the same virtual server as the one that is running your portal site. You can create a Web site and define the folder as a managed path within SharePoint Portal Server, or drop the ASP.NET pages into the SharePoint Portal Server folders. From that moment on, all of the SharePoint Web controls you can use on the SharePoint Web Part pages can be embedded on your own custom pages.

To use the SearchBox and SearchResults Web controls, you have to reference both Microsoft.SharePoint.Portal.dll and Microsoft.SharePoint.dll within your ASP.NET project. You can add the SearchBox at run time to your pages by creating an instance of it, modify the properties, and then add the control to a container control on the page such as the PlaceHolder control.

SearchBox sb = new SearchBox();
sb.Title = "Search SharePoint from here";
sb.CompactMode = true;
sb.SearchResultPageURL = "CustomSearchResults.aspx";
PlaceHolder1.Controls.Add(sb);

If you only want a simple version of the search box, you can set the CompactMode property to true. The search box in compact mode displays only the caption (set by the Title property), a text box for the user to fill in the keyword, and the button to execute the query (Figure 4). An important property to set at the level of the SearchBox is the SearchResultPageURL. This property sets the URL to the page that displays the results of the query. On that page, you use an instance of the SearchResults control to display the results of the execution of the query.

Figure 4. SearchBox on an ASP.NET page

The SearchBox and the SearchResult Web controls both generate HTML in which you find some default SharePoint-related cascading style sheet (CSS) classes. You can create a custom CSS file or add the style sheet that comes with SharePoint Portal Server (SPS.CSS). You can find the SPS.CSS style sheet in C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\LAYOUTS\1033\STYLES.

The SearchResults Web control has a number of properties that define its look and feel. You can, for example, set the Title and the TextForNoResults properties (Figure 5).

SearchResults sr = new SearchResults();
sr.Title = "Results of the search";
sr.TextForNoResults = "Sorry, nothing found";
PlaceHolder1.Controls.Add(sr);

Figure 5. Displaying the SearchResults Web control on an ASP.NET page

The four QueryTemplate properties are more important. The SearchResults control stores a template for the query definition internally. This template contains four parts, each of which you can modify according to your custom needs:

  • A QueryTemplateSelectPart for the SELECT part of the template.
  • A QueryTemplateFromPart for the FROM part of the template.
  • A QueryTemplateWherePart for the WHERE part of the template.
  • A QueryTemplateOrderByPart for the ORDER BY part of the template.

You can go a step further and create your own ASP.NET server controls that inherit from the SharePoint Web controls, thereby providing additional functionality or predefining some of the members exposed by these Web controls.

To create these types of ASP.NET server controls, you just create a new Web control library project and create a class that inherits from the Microsoft.SharePoint.Portal.WebControls.SearchBox class and another class that inherits from the Microsoft.SharePoint.Portal.WebControls.SearchResults class.

Working with the Query Service Web Service

SharePoint Portal Server also exposes its search functionalities through an XML Web service. Working with the Web service allows developers to incorporate SharePoint Portal Server search into smart-client applications such as Microsoft Windows, Pocket PC applications, and the Microsoft Office System applications. ASP.NET Web applications that cannot attach themselves to the SharePoint Portal Server context are also candidates for this approach. A good example is an existing intranet site running on one of your front-end Web servers where you allow a user to execute SharePoint Portal searches.

As a first example, we'll show you how to create a small Windows-based application that lets the user enter a keyword and execute a SharePointPSSearch query with it. After that, we'll demonstrate how the Query Service Web service can also be consumed within the Office 2003 Research task pane.

Calling the Query Service Web Service Using a Windows Application

To start, we create a small Windows-based application and add a Web reference to search.asmx (Figure 6). Based on the Web Service Description Language (WSDL) returned by the Web server hosting the Web service, Visual Studio .NET creates a proxy class for you and prepares your project for the consumption of the SharePoint Portal Server Query Service Web service. The Web service is accessible through the http://myportal/_vti_bin/search.asmx URI.

Figure 6. Adding the Web reference to the Query Service Web service

Of the number of Web methods exposed by the Web service, two methods are important for this example: Query and QueryEx. You can use either to execute a SharePoint Portal Server query. Both accept a query encapsulated in an XML string and defined by the urn:Microsoft.Search.Query namespace, however, their return values differ. The Query method returns an XML string, while the QueryEx method returns XML that de-serializes into an ADO.NET DataSet automatically.

The XML for the request can contain the keyword, or it can contain a query formulated in the Microsoft SQL Syntax for Full-text Search (MSSQLFT) dialect.

Following is a template you can use for the simple query on keywords.

<?xml version="1.0" encoding="utf-8" ?
<QueryPacket xmlns="urn:Microsoft.Search.Query" Revision="1000">
  <Query domain="QDomain">
   <SupportedFormats>
     <Format>urn:Microsoft.Search.Response.Document.Document</Format>
   </SupportedFormats>
   <Context>
      <QueryText language="en-US" type="STRING">keyword</QueryText>
   </Context>
  </Query>
</QueryPacket>

Here is the same template, formulated in the MSSQLFT syntax.

<?xml version="1.0" encoding="utf-8" ?>
<QueryPacket xmlns="urn:Microsoft.Search.Query" Revision="1000">
  <Query domain="QDomain">
   <SupportedFormats>
      <Format>urn:Microsoft.Search.Response.Document.Document</Format>
   </SupportedFormats>
   <Context>
      <QueryText language="en-US" type="MSSQLFT">keyword</QueryText>
   </Context>
   <Range><StartAt>1</StartAt><Count>5</Count></Range>
  </Query>
</QueryPacket>

You must take care of the credentials you want to use when consuming the Web service. The account must be defined as a SharePoint Portal Server user on the portal site. The credentials can be either those of the currently logged-on user, or you can use the System.Net.NetWorkCredential class to specify the name, domain, and password of the account you want to use.

try
{
   QueryService query = new QueryService();
   query.Credentials = System.Net.CredentialCache.DefaultCredentials;
   string results = query.Query(queryString);
}
catch(Exception ex)
{
   MessageBox.Show("Error consuming Web service or processing the 
   results. \n\n" + ex.ToString());
}

The Query method returns the results in XML format defined by the urn:Microsoft.Search.Response namespace.

<ResponsePacket xmlns="urn:Microsoft.Search.Response">
  <Response domain="QDomain">
    <Copyright>Microsoft (c) Office SharePoint (r) Portal 
    Server 2003</Copyright>
    <Range>
      <StartAt>1</StartAt>
      <Count>10</Count>
      <TotalAvailable>12</TotalAvailable>
      <Results>
        <Document type="Sites in site directory" relevance="672"
        xmlns="urn:Microsoft.Search.Response.Document">
          <Title>SharePoint Cursus</Title>
          <Action>
            <LinkUrl size="44738">
            http://limassol:83/sites/vhlora/SharePoint Cursus</LinkUrl>
          </Action>
          <Description>SharePoint Cursus</Description>
          <Date>2004-06-16T04:01:10</Date>
        </Document>
   . . .      </Results>
    </Range>
    <Status>SUCCESS</Status>
  </Response>
</ResponsePacket>

You can process this incoming XML using an XSLT transformation file or you can load the XML string into a System.Xml.XmlDocument object. You can display the result in multiple ways to the end-user.

Microsoft .NET Framework developers can use the QueryEx method to return the results as an ADO.NET DataSet. Working with the QueryEx method allows you to execute a SharePoint Portal Server query and easily bind the results to a control that you can use to display the response to the user. Using the QueryEx method requires less work to process the results.

try
{
   QueryService query = new QueryService();
   query.Credentials = System.Net.CredentialCache.DefaultCredentials;
   DataSet ds = query.QueryEx(queryString);
   dataGridResults.DataSource = ds.Tables[0];
}
catch(Exception ex)
{
   MessageBox.Show("Failure in consuming Web service or processing 
   the results. \n\n" + ex.ToString());
}

Consuming the Query Service Web Service from the Office Research Task Pane

Microsoft Office 2003 users can consume Web services directly from within the Office products and Microsoft Internet Explorer without any coding if they use the Research task pane.

To see this Research task pane in action (Figure 7), you can open or create a Microsoft Office Word document, and then click Research on the Tools menu.

Figure 7. Research task pane

The drop-down list (showing All Reference Books as the selected item in Figure 7) lists the Web services registered as a Research Service.

**Note   **The Web services need to accept and respond with XML that is defined by the Research Service XML Schemas.

Users can type a word in the text box or they can transfer a word in the active document to the text box by clicking on the word while pressing the ALT key. Depending on the selection you have made in the drop-down, list, the word is sent to all the registered Web services or only to the selected one. After processing the incoming request, each of the Web services returns its result. The results are then aggregated and displayed in the pane (as shown in Figure 10).

Office 2003 comes with a number of Web services that are already registered. Examples include the Microsoft Encarta Encyclopedia, a translation service, and more.

Developers who create Web services that they want to register and use in the Research task pane have to accept and return XML defined by specific schemas. These are well documented in the Microsoft Office 2003 Research Service SDK available for download in the Microsoft Download Center (see Additional Resources).

The good news is that the Query Service Web service follows these schemas and you can use it immediately from within the Research pane.

Follow these steps to register the service:

  1. In the Research task pane, click the Research options link to open the Research Options dialog box.

  2. Click Add Services.

  3. In Address, type in the URL to the search.asmx exposed by the portal site (Figure 8).

    Figure 8. Adding the Search Service to the Research task pane

    A confirmation message appears with the list of services that can be activated (Figure 9).

    Figure 9. A successful registration

  4. Close all dialog boxes.

After you register the service, you can start using it. Simply select the new service in the drop-down list so that you can limit the search to that one service. Type a word into the text box (for example, "sharepoint") and have the SharePoint Portal Server search engine execute your query. Both portal and non-portal content are displayed in the pane (Figure 10).

Figure 10. The SharePoint Search Results in the Research task pane

Conclusion

SharePoint Portal Server 2003 gives developers many scenarios to incorporate search capabilities within their own applications or extensions of portal or team sites. This article provided a general overview starting with the HTTP GET, in a discussion of the QueryProvider class within the object model, and of the Web controls and the search Web services involved to execute the queries remotely.

Additional Resources

A Developer's Introduction to Web Parts

Building Web Parts for Microsoft SharePoint Products and Technologies (Part I)

Building Web Parts for Microsoft SharePoint Products and Technologies (Part II)

Building Web Parts for Microsoft SharePoint Products and Technologies (Part III)

Microsoft SharePoint Products and Technologies 2003 Software Development Kit (SDK)

Microsoft Office 2003 Research Service Software Development Kit (SDK)

About the Author

Patrick Tisseghem is managing partner at U2U, a .NET training services company based in Brussels. His main areas of expertise are the Microsoft .NET Framework and all the products and technologies that relate to the information worker. In this role, he is evangelizing SharePoint Portal Server and Office development for Microsoft in the Benelux.

This article was developed in partnership with A23 Consulting.