Of Code and Me

Somewhere to write down all the stuff I'm going to forget and then need

Search Webservice for SharePoint / Search Server with configurable timeout December 10, 2009

Filed under: C#,Search Server — Rupert Bates @ 5:11 pm

Anyone who has used Microsoft Search Server or the search.asmx Query service in Sharepoint to search a site of any size has probably run into the System.ServiceProcess.TimeoutException error. This is caused by the search failing to complete within 10 seconds at which point sharepoint throws this exception.

Anyone who has then Googled this error will probably have found out that this 10 second limit is (amazingly) hard coded into the QueryService class and so cannot be extended. The only suggestion I have seen for getting round this is to write your own webservice which uses the same classes as QueryService to perform a search and so that is what I have done.

I should point out that this is not really my code, I used Reflector to decompile the QueryService class and then made some modifications to get it to compile (see notes), so this really is the same code that search.asmx uses.

To make use of this code:
1. Download and unzip the files

2. Copy:

SearchWithTimeout.asmx
SearchWithTimeoutWsdl.aspx
SearchWithTimeoutDisco.aspx

To: c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI

3. Install Guardian.SearchServer.dll into the GAC. The easiest way to do this is to copy the dll to C:\Windows\Assembly

That’s it, just use this searchWithTimeout.asmx in the same way you would have used search.asmx; add a service reference then call the QueryEx method passing in the same queryXml along with the timeout in milliseconds:

var searchServiceQuery = new SearchServer.SearchWithTimeoutSoapClient();
            
            searchServiceQuery.ClientCredentials.Windows.ClientCredential.Domain = ConfigurationManager.AppSettings["SearchServer.Domain"];
            searchServiceQuery.ClientCredentials.Windows.ClientCredential.UserName = ConfigurationManager.AppSettings["SearchServer.Username"];
            searchServiceQuery.ClientCredentials.Windows.ClientCredential.Password = ConfigurationManager.AppSettings["SearchServer.Password"];
            searchServiceQuery.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            searchServiceQuery.ClientCredentials.Windows.AllowNtlm = true;

            //Verify that the Search Server is up and running
            if (string.Compare(searchServiceQuery.Status(), "ONLINE", true) != 0)
                throw new Exception("The Search Server isn't online.");

            var timeout = int.Parse(ConfigurationManager.AppSettings["SearchServer.TimeoutInMilliseconds"]);
            var searchResults = searchServiceQuery.QueryEx(query, timeout);
            
            searchServiceQuery.Close();

Notes

In the assembly in which you reference the webservice you need to change the Config setting in System.ServiceModel\bindings\basicHttpBinding\binding
to set the mode to “TransportCredentialOnly” and the Transport clientCredentialType to “Windows” or “NTLM” (this is the same as with the original Search Server webservice, more info here). This should look as follows:

          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>

My webservice only has a subset of the methods that can be found on search.asmx/QueryService, this is because the missing methods used classes which were internal to Microsoft.Office.Server.Search.dll so I couldn’t reproduce their functionality. If you need the other methods then reference both webservices.
The methods I have reproduced are:

  • QueryEx
  • Query
  • Status
  • GetSearchMetadata

I have only tested Status and QueryEx, so I would be keen to hear from anyone on whether the other methods work as expected.
I have also had to make the following changes (all of them because the original code used internal classes):

  1. removed some logging code that was in the original webservice
  2. changed an exception type
  3. exceptions do not load messages from the resource file
Advertisements
 

One Response to “Search Webservice for SharePoint / Search Server with configurable timeout”

  1. mriganka Says:

    Thanks for this nice article.
    Now I overcame with the timeout issue, but when I am searching for keywords which should return 100K results my application is not working. It is not throwing any error but the application still running for 30/40 minutes with no result.
    Any solution is highly appreciated.

    Thanks


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s