Winnersh Triangle Web Solutions Limited

Timesaving tools for software developers

HOME | NEWS | PRODUCTS | DOWNLOADS | SPECIAL OFFERS | ORDERING | UPGRADES | CONTACT 
 
SEARCH WEBSITE
Search Website

PRODUCTS
The Website Utility
.NET Documentation Tool
ASP Documentation Tool
ASP.NET Documentation Tool
VB 6.0 Documentation Tool
PHP Documentation Tool
SQL Documentation Tool
MySQL Documentation Tool
JavaScript Banner Ad Rotator
Indexing Service Companion
HubPages Success Guide
Product Ordering
Special Offers

SERVICES
Articles & Whitepapers
Business Software
Documentation Portal
Client Success Stories
Sell Our Products
Our Blog

Using the Windows Indexing Service with C#

The Windows Indexing Service is used to index files via the file system and allow them to be searched through a set of APIs. One popular use of Indexing Services is to provide a website search facility for websites hosted on Internet Information Services (IIS).

This page describes how to use Windows Indexing Services from within ASP.NET using the C# programming language. The article is "fully Dot Net friendly" - i.e. it describes how search results can be retrieved as an ADO.NET DataTable and displayed in a DataGrid (using a GridView would use near identical code to that shown). This allows search results to be manipulated and presented in ways that were not easily possible using classic ASP, such as by making use of the built in data column sorting functionality, and the ability to use paging for the search results.

This article assumes that you know how to use Indexing Services and are familiar with the concepts of creating search catalogs. The code sample assumes that an Indexing Service search catalog called searchcatalog has previously been configured on your web server.

The code samples will work with Index Server on Windows NT 4.0 systems and Indexing Services on Windows Server 2000/2003/XP systems.

Using the C# code samples

There are two source code files shown. The ASP.NET file is called IndexingServiceWithCSharp.aspx. It must be associated with a code behind page called IndexingServiceWithCSharp.aspx.cs.

Note that if you want to use this sample source code to show users a graphical representation of how relevant each search result is to their query then you will need to create a set of images called 1bars.png to 10bars.png inclusive, then put them in an images subfolder. Alternatively matches may be represented as percentages, or omitted altogether.

How the C# code works

The ASP.NET page contains two web controls. A label control called LabelNumberOfResults is used to display the number of search results. It is also used to display an errors encountered during a search.

The page also contains a DataGrid control called DataGridSearchResults. This control is used to display the search results. There are columns within this DataGrid for displaying a document's rank, its title and the date the document was last updated. The title is a hyperlink to the actual document itself.

Note that further columns can of course be added if other document properties need to be displayed. Although a DataGrid is used in this example, other web controls can be useful for displaying search results - in some cases it would be appropriate to use the Repeater control for example.

The sample search doesn't contain a form for a user to enter a search query - for now the query is held within the C#'s QueryText string variable. This value could of course be assigned using the value of a textbox.

The name of the Indexing Service search catalog is contained in the CatalogName variable.

The document rank returned by the Windows Indexing Service has a value of between 0 and 1000 (with 1000 being the most closely matching document). The sample C# code reduces this to a figure between 0 and 10, which then allows the rank of each document to be shown graphically through a set of images with the filenames 0bars.png to 10bars.png inclusive.

Ordering Search Results

It is useful to be able to order search results. One way of achieving this would be to create a DataView from the search results data, and use that to populate the DataGrid:

//Create a DataView from the search results data   
DataView SearchDataView = new DataView(SearchResultsTable.Tables[0]);  
  
//Sort the search results by rank  
SearchDataView.Sort = "PageRank DESC";  
  
DataGridSearchResults.DataSource = SearchDataView;

Finally, if you are interested in extending the functionality of Indexing Services to allow content on any web server or ODBC database to be indexed and searchable, then take a look at our Indexing Service Companion product.

C# Example Source Code

The source code of the ASP.NET page IndexServer.aspx:

<%@ Page language="c#" Codebehind="IndexServer.aspx.cs" AutoEventWireup="false" Inherits=" BRETTB.IndexServer" %>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >  
<HTML>  
    <HEAD>  
        <title>Indexing Service Test</title>  
        <meta name="CODE_LANGUAGE" Content="C#">  
        <meta name="vs_defaultClientScript" content="JavaScript">  
        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">  
    </HEAD>  
    <body MS_POSITIONING="FlowLayout">  
        <form id="Form1" method="post" runat="server">  
            <asp:Label id="LabelNumberOfResults" runat="server"></asp:Label>  
            <p><asp:DataGrid id="DataGridSearchResults" runat="server" HeaderStyle-Font-Bold="True" AutoGenerateColumns="False"  
                    BorderWidth="0" AllowCustomPaging="True">  
                    <Columns>  
                        <asp:BoundColumn DataField="RankImageHTML" HeaderText="Rank"></asp:BoundColumn>  
                        <asp:HyperLinkColumn DataTextField="DocumentTitle" DataNavigateUrlField="DocumentURL" HeaderText="Document Title"></asp:HyperLinkColumn>  
                        <asp:BoundColumn DataField="DocumentDate" HeaderText="Last Updated"></asp:BoundColumn>  
                    </Columns>  
                </asp:DataGrid></p>  
        </form>  
    </body>  
</HTML>

The source code of the code behind page IndexServer.aspx.cs:

using System;  
using System.Collections;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Web;  
using System.Web.SessionState;  
using System.Web.UI;  
using System.Web.UI.WebControls;  
using System.Web.UI.HtmlControls;  
using System.Data.OleDb;  
using System.Data.SqlClient;  
  
  
namespace BRETTB  
{  
    /// <summary>  
    /// Summary description for IndexServer.   
    /// </summary>  
    public class IndexServer : System.Web.UI.Page  
    {  
        protected System.Web.UI.WebControls.DataGrid DataGridSearchResults;  
        protected System.Web.UI.WebControls.Label LabelNumberOfResults;  
      
        private void Page_Load(object sender, System.EventArgs e)  
        {  
            string QueryText = "asp alliance"; //The search string
            string CatalogName = "searchcatalog"; //The name of your Index Server catalog
            int NumberOfSearchResults = 0;  
            DataSet SearchResults = new DataSet();  
  
            //Prevent SQL injection attacks - further security measures are recommended  
            QueryText = QueryText.Replace("'", "''");  
  
            //Build the search query  
            string SQL = "SELECT doctitle, vpath, Path, Write, Size, Rank ";  
            SQL += "FROM \"" + CatalogName + "\"..SCOPE() ";  
            SQL += "WHERE";  
            SQL += " CONTAINS(Contents, '" + QueryText + "') ";  
            SQL += "AND NOT CONTAINS(Path, '\"_vti_\"') ";  
            SQL += "AND NOT CONTAINS(FileName, '\".ascx\" OR \".config\" OR \".css\"') ";  
            SQL += "ORDER BY Rank DESC";  
  
            //Connect to Index Server and perform search query  
            try   
            {  
                OleDbConnection IndexServerConnection = new OleDbConnection("Provider=msidxs;");  
                OleDbCommand dbCommand = new OleDbCommand(SQL, IndexServerConnection);  
  
                OleDbDataAdapter IndexServerDataAdapter = new OleDbDataAdapter();  
                IndexServerDataAdapter.SelectCommand = dbCommand;  
                  
                IndexServerDataAdapter.Fill(SearchResults);  
                NumberOfSearchResults = SearchResults.Tables[0].Rows.Count;  
            }  
            catch (Exception ExceptionObject)  
            {  
                //Query failed so display an error message  
                NumberOfSearchResults = 0;  
                LabelNumberOfResults.Text = "Problem with retrieving search results due to: " + ExceptionObject.Message;  
                DataGridSearchResults.Visible = false;  
  
            }  
  
            //Build a datatable for search results  
            DataTable SearchResultsTable = new DataTable("SearchResults");  
            SearchResultsTable.Columns.Add(new DataColumn("DocumentRank", typeof(int)));   
            SearchResultsTable.Columns.Add(new DataColumn("RankPercentage", typeof(int)));   
            SearchResultsTable.Columns.Add(new DataColumn("RankNumber", typeof(int)));  
            SearchResultsTable.Columns.Add(new DataColumn("RankImageHTML", typeof(String)));   
            SearchResultsTable.Columns.Add(new DataColumn("DocumentURL", typeof(String)));   
            SearchResultsTable.Columns.Add(new DataColumn("DocumentTitle", typeof(String)));   
            SearchResultsTable.Columns.Add(new DataColumn("DocumentDate", typeof(String)));  
  
            if (NumberOfSearchResults > 0)  
            {  
                LabelNumberOfResults.Text = NumberOfSearchResults + " document(s) were found matching the query '" + QueryText + "'";  
  
                foreach (DataRow SearchResultDataRow in SearchResults.Tables[0].Rows)  
                {  
  
                    //Determine the document's date  
                    DateTime DocumentDate;  
                    try  
                    {  
                        DocumentDate = Convert.ToDateTime(SearchResultDataRow["Write"].ToString());  
                    }   
                    catch  
                    {  
                        DocumentDate = DateTime.Now;  
                    }  
  
                    //Determine the document's title  
                    string DocumentTitle = SearchResultDataRow["doctitle"].ToString();  
                    if (DocumentTitle.Length < 2)  
                    {  
                        DocumentTitle = "untitled document";  
                    }  
  
                    //Determine the document's rank  
                    int RankNumber = 0;  
                    int DocumentRank = Convert.ToInt32(SearchResultDataRow["Rank"].ToString());  
                    int RankPercentage = DocumentRank;  
                    RankPercentage = Convert.ToInt32(Math.Round(Convert.ToDouble(RankPercentage / 10), 0));  
  
                    if (DocumentRank > 900)  
                    {  
                        RankNumber = 10;  
                    }   
                    else if (DocumentRank > 800)  
                    {  
                        RankNumber = 9;  
                    }   
                    else if (DocumentRank > 700)  
                    {  
                        RankNumber = 8;  
                    }  
                    else if (DocumentRank > 600)  
                    {  
                        RankNumber = 7;  
                    }  
                    else if (DocumentRank > 500)  
                    {  
                        RankNumber = 6;  
                    }  
                    else if (DocumentRank > 400)  
                    {  
                        RankNumber = 5;  
                    }  
                    else if (DocumentRank > 300)  
                    {  
                        RankNumber = 4;  
                    }  
                    else if (DocumentRank > 200)  
                    {  
                        RankNumber = 3;  
                    }  
                    else if (DocumentRank > 100)  
                    {  
                        RankNumber = 2;  
                    }  
                    else if (DocumentRank > 0)  
                    {  
                        RankNumber = 1;  
                    }  
                    else  
                    {  
                        RankNumber = 1;  
                    }  
                    string RankingAltTag = RankPercentage + " percent match";  
                    string RankImageHTML = "<img src=\"images/" + RankNumber + "bars.png\" width=\"80\" height=\"17\" alt=\"" + RankingAltTag + "\"> ";  
  
                    //Populate a DataRow for the current search result  
                    DataRow SearchResultsRow = SearchResultsTable.NewRow();  
                    SearchResultsRow["DocumentRank"] = SearchResultDataRow["Rank"].ToString();  
                    SearchResultsRow["RankPercentage"] = RankPercentage;  
                    SearchResultsRow["RankNumber"] = RankNumber;  
                    SearchResultsRow["DocumentURL"] = SearchResultDataRow["vpath"].ToString();  
                    SearchResultsRow["DocumentTitle"] = DocumentTitle;  
                    SearchResultsRow["RankImageHTML"] = RankImageHTML;  
                    SearchResultsRow["DocumentDate"] = DocumentDate.ToString("dd MMMM yyyy");  
                    SearchResultsTable.Rows.Add(SearchResultsRow);   
                }  
  
                //Bind DataTable to DataGrid  
                DataGridSearchResults.Visible = true;      
                DataGridSearchResults.DataSource = SearchResultsTable;  
                DataGridSearchResults.DataBind();  
            }  
            else   
            {  
                //No search results were found for the query  
                DataGridSearchResults.Visible = false;  
                LabelNumberOfResults.Text = "No document(s) were found matching the query '" + QueryText + "'";  
  
  
            }  
  
        }  
  
        #region Web Form Designer generated code  
        override protected void OnInit(EventArgs e)  
        {  
            //   
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.  
            //   
            InitializeComponent();  
            base.OnInit(e);  
        }  
          
        /// <summary>   
        /// Required method for Designer support - do not modify  
        /// the contents of this method with the code editor.  
        /// </summary>   
        private void InitializeComponent()  
        {      
            this.Load += new System.EventHandler(this.Page_Load);  
  
        }  
        #endregion  
    }  
}


© Copyright 2002 - 2010 Winnersh Triangle Web Solutions Limited. Registered company number: 4493816.       Sales Policy | Site Map  
documentation portal cure for RSI pain