LANGUAGES: VB.NET | C#
ASP.NET VERSIONS: 2
Search Box
Master the Art of Search with this Custom Control that Provides the Ability to Search
Your Site, Other Sites, or the Entire Web
Every respectable Web site of significance needs to provide search capabilities
so users can quickly find the information they seek. But how does a Web developer
provide such functionality? There are myriad ways one might go about this. For example,
if all the content is stored within SQL Server, its full text searching capabilities
may be of use. But because that’s frequently not an option, it’s not too difficult
to dream about creating a custom system that matches keywords to pages. But why
reinvent the wheel? If your Web site is publicly available on the Internet, odds
are it has already been thoroughly indexed by Google, MSN Search, and any number
of other search engines.
Leave It to the Professionals
The custom SearchBox control I’ve created harnesses the power of Google and MSN
Search to provide your Web site with all the searching muscle it needs. The SearchBox
control (shown in Figure 1 and used at the bottom of this page)
is capable of using a couple different techniques to
do the searches, depending on how you configure it.

Figure 1: The SearchBox custom control
can return search results for a specific Web site or the entire Web.
The first and simplest technique builds an appropriate URL string and redirects
the user to it. At this point the search is handed off to Google or MSN Search,
whichever has been selected in the control’s SearchProvider property. For example,
if searching the Web for information about towels, the user could be redirected
to the following URL:
http://search.msn.com/results.aspx?q=towels
If the user wanted to search only MSDN for information about Babel Fish, this URL
could be used:
http://www.google.com/search?q=babel+fish+site%3Amsdn.microsoft.com
Luckily, both Google and MSN Search use similar query strings, so the same code
can be used to build the query string no matter which search site is being used.
To use this Firefox-compatible SearchBox control to return search results for a
specific site (such as your Web site), set its SearchSiteOnly property to True and
set the SearchSite property to the public URL of the Web site. If the SearchSiteOnly
property is set to False, the SearchSite property will be ignored and the entire
Internet will be searched for the word(s) in the Text property. To allow the users
to choose whether they’d like to search the entire Web or a specific site, make
sure the ShowSearchOptions property is set to True. You can also configure the text
that will be displayed for both of these radio buttons with the SearchTheWebText
property and the SearchSiteText property.
(advertisement)
The ButtonBelow property specifies whether the Search button should appear beside
the search TextBox or below it. The ButtonText property lets you configure the text
that appears on the button.
All these options to configure the appearance of the control are nice, but you don’t
even have to show the control to use it. You could set its visible property to False,
configure some of the properties described above, and call the SearchBox’s Search
method to kick off the search.
When the Search button is clicked (or the control’s Search method is called) the
user will be forwarded to the standard Google or MSN Search Web site with the results
immediately displayed, as shown in Figure 2.

Figure 2: One way to use the SearchBox
is to have it redirect the user and their search request to Google’s or MSN Search’s
standard results page.
This approach works well, and gives the user great results in a hurry. The only
downside is that it requires the user to leave your site to get the search results.
Web developers that are trying to increase traffic tend to cringe at the thought
of sending users away, even if it’s just for a quick search that sends them right
back into their site. If only there were a good way to get the search results on
the server and then output the results into one of your own pages ...
MSN Search Web Services
Luckily, both Microsoft and Google have introduced Web services that we can call
to get search results via code. I’ve chosen to take advantage of Microsoft’s Web
service for this version of the SearchBox control because it provides more features
than Google’s — and has less restrictive terms of use. And have you noticed how
much MSN Search has improved recently? It looks like Google may have some serious
competition in the search arena, after all.
The SearchBox encapsulates the complexities of calling the MSN Search Web Service.
If you choose to use this technique, you need to set the SearchBox’s SearchProvider
property to MSNWebService. You also need to set the MSNApplicationID property to
the ID you got free from Microsoft. To get an ID, or to learn more about the MSN
Search Web Service, visit
http://msdn.microsoft.com/msn/gettingstarted/searchstart/.

Figure 3: This page only required
a couple lines of code to query the MSN Search Web Service and display the results
in a GridView.
Now when the user clicks on the Search button, the control will call the Web service,
retrieve the search results, and raise a SearchResultsReady event to the page. A
DataTable will be passed as a parameter to this event, allowing you to do whatever
you wish with the results. Figure 3 shows a basic page that received search results
from a SearchBox control and displayed the results in a GridView control using almost
no code:
Protected
Sub SearchBox1_SearchResultsReady(ByVal
_
SearchResults As
System.Data.DataTable) _
Handles SearchBox1.SearchResultsReady
GridView1.DataSource = SearchResults
GridView1.DataBind()
End
Sub
Many Web sites prefer to have some kind of search textbox on nearly every page,
and then display the results on a specific search page. That’s where the PostBackURL
property comes in. Set this property to the URL of your special search page; then,
in the code behind of that search page, use a couple lines of code to receive the
posted values and execute the search:
Protected
Sub Page_Load(ByVal
sender As Object,
_
ByVal e
As System.EventArgs) Handles
Me.Load
If
Request("SearchBox1$text")
IsNot Nothing Then
SearchBox1.Text = Request("SearchBox1$text")
SearchBox1.Search()
End
If
End
Sub
That’s about all you need to know to start using the SearchBox control, which is
available for download (see end of article for details). An overview of the unique
properties, events, and methods are shown in Figure 4. Simply drag
the SearchBox.dll into your Visual Studio 2005 toolbox, then drag it onto any Web
form(s) and you should be good to go.
|
Unique SearchBox Members
|
Description
|
|
ButtonBelow property
|
This property specifies whether the search button should appear beside the search
TextBox or below it.
|
|
ButtonText
property
|
This property specifies the text that should appear on the search button.
|
|
MSNApplicationID property
|
Set this to the application id Microsoft gave you.
|
|
PostBackURL property
|
Set this property to have the control post to another page to display the results.
|
|
SearchProvider property
|
Set this to Google, MSN, or MSNWebService to use the associates search technique
|
|
SearchSite property
|
If you’d like to search only one specific web site (such as your web site) put the
URL of that public web site into this property
|
|
SearchSiteOnly property
|
Set this property to True to only search the site specified in the
SearchSite property.
|
|
SearchSiteText property
|
Set this property to the text that you’d like to be displayed for the Search This
Site radio button.
|
|
SearchTheWebText property
|
Set this property to the text that you’d like to be displayed for the Search The
Web radio button.
|
|
ShowSearchOptions property
|
Set this property to True to display the radio buttons, of False to hide them.
|
|
SearchResultsReady event
|
This event provides a DataTable filled with the results from the MSN Search Web
Service
|
|
Search method
|
Call this method to initiate the search without requiring the search button to be
clicked.
|
Figure 4: The SearchBox control provides
a dozen members to make searching quick and easy.
So How Does It Work?
The SearchBox is a custom Web server control. The easiest way to create a custom
Web server control is to first create a Web Control Library. This may not be as
easy as it sounds if you’ve recently upgraded to Visual Studio 2005, because Microsoft
moved things around quite a bit. As you can see in Figure 5, the option for a Web
Control Library can be found under the Windows category beneath your language of
choice. Not a very intuitive place to put it, in my opinion, but it’s easy enough
to find once you know where it is.
Figure 5: The Web Control Library
project type is now located under the Windows category in the Visual Studio 2005
New Project dialog box.
The SearchBox class inherits from WebControl and implements INamingContainer. Composition
is used for this control (instead of Rendering), meaning essentially that, internally,
controls are instantiated from within the CreateChildControls event. The source
code for most of the properties is fairly boilerplate, so I’ve only listed a few
of the more interesting ones in Figure 6.
<Bindable(True), Category("Appearance"),
_
Description("Shows/Hides the search option radio buttons"), _
DefaultValue(True)> _
Public
Property ShowSearchOptions()
As Boolean
Get
If
ViewState("ShowSearchOptions")
IsNot Nothing Then
Return
_
Convert.ToBoolean(ViewState("ShowSearchOptions"))
Else
Return True 'default
End
If
End Get
Set(ByVal value As Boolean)
ViewState("ShowSearchOptions")
= value
End Set
End
Property
Public
Enum SearchProviderEnum
MSN = 0
Google = 1
MSNWebService = 2
End
Enum
Dim
_spe As SearchProviderEnum
<Bindable(True), Category("Behavior"),
DefaultValue(0), _
Description("Which search method to use")> _
Public
Property SearchProvider()
As SearchProviderEnum
Get
Dim s As String
= CStr(ViewState("SearchProvider"))
If s Is Nothing
Then
Return _spe
Else
Select Case Convert.ToInt32(s)
Case 0
Return SearchProviderEnum.MSN
Case 1
Return SearchProviderEnum.Google
Case 2
Return SearchProviderEnum.MSNWebService
End Select
End If
End
Get
Set(ByVal value As SearchProviderEnum)
_spe = value
ViewState("SearchProvider")
= value
End
Set
End
Property
Figure 6: The source code for a few
of the more interesting SearchBox properties.
The ShowSearchOptions property is fairly standard, including a few attributes to
make the design time experience friendlier. ViewState is used to ensure values are
stored between page postbacks. The SearchProviderEnum enumeration is used by the
SearchProvider property to allow the developer to select Google, MSN, or MSN’s Web
service.
The control is essentially rendered as a TextBox, Button, and two RadioButtons.
These child controls are created and configured from within the overridden CreateChildControls
event, as shown in Figure 7.
Private
WithEvents _txt As
TextBox
Private
WithEvents _radio1 As
RadioButton
Private
WithEvents _radio2 As
RadioButton
Private
WithEvents _btn As
Button
Protected
Overrides Sub
CreateChildControls()
MyBase.CreateChildControls()
'create a
container for all the controls
Dim
pnl As New Panel()
pnl.ToolTip =
Me.ToolTip
pnl.CssClass =
Me.CssClass
pnl.BackColor =
Me.BackColor
pnl.ForeColor =
Me.ForeColor
pnl.SkinID =
Me.SkinID
'create the
textbox & add it to the container
_txt = New
TextBox
_txt.Text =
Me.Text
_txt.ID =
"text"
pnl.Controls.Add(_txt)
'create the
button
_btn = New
Button
_btn.Text =
Me.ButtonText
_btn.PostBackUrl =
Me.PostBackURL
_btn.ID =
"button"
pnl.DefaultButton = _btn.ClientID
If
Me.ButtonBelow = False
Then pnl.Controls.Add(_btn)
pnl.Controls.Add(New
LiteralControl("<br/>"))
'create the
search site/web radio buttons
If
Me.ShowSearchOptions Then
_radio1 =
New RadioButton
_radio1.Text = Me.SearchSiteText
_radio1.GroupName =
"Search"
_radio1.Checked = Me.SearchSiteOnly
_radio1.Style.Add(HtmlTextWriterStyle.FontSize,
_
"x-small")
_radio1.ID =
"SearchSite"
pnl.Controls.Add(_radio1)
_radio2 =
New RadioButton
_radio2.Text = Me.SearchTheWebText
_radio2.GroupName =
"Search"
_radio2.Checked = Not Me.SearchSiteOnly
_radio2.Style.Add(HtmlTextWriterStyle.FontSize,
_
"x-small")
_radio2.ID =
"SearchWeb"
pnl.Controls.Add(_radio2)
pnl.Controls.Add(New LiteralControl("<br/>"))
End
If
If
Me.ButtonBelow Then
pnl.Controls.Add(_btn)
Controls.Add(pnl)
End
Sub
Figure 7: The CreateChildControls
method contains the code for instantiating and configuring all the child controls.
A panel control contains all the child controls so they’ll stay together in the
same area of the Web form, and a few of the base control properties are piped through
to this panel. Next, the TextBox and Button are instantiated. The Button is configured
to be the panel’s default button, which is a new feature of ASP.NET 2.0. If the
Button is configured to be beside the TextBox, then it is immediately rendered;
otherwise, the rendering is delayed until the end of this subroutine. The RadioButtons
are then instantiated and configured if the ShowSearchOptions property is set to
True. Finally, all the controls are added to the containing panel control.
Figure 8: The Search method contains
most of the logic for performing searches by assembling the correct URL and QueryString
and redirecting the user to it.
Figure 8 shows the Search function, which (intuitively) contains
the meat of the logic for performing the simple search. It starts by accepting a
search string; otherwise, it uses the search string that was previously supplied
to the Text property. If the control was configured to use the MSN Web Search Service,
then control is handed off to another function (listed in Figure 9)
and an event is raised with the resulting DataTable. Otherwise, the URL and QueryString
are concatenated together and the user is redirected to that address.
'Queries the MSN search web service and returns a datatable
'containing the results.
'For more info on the MSN search web service, start here:
'http://msdn.microsoft.com/msn/gettingstarted/searchstart/
Protected
Function GetMSNWebSearchWebServiceResults() _
As
DataTable
'initialize variables
Dim s As New MSNSearchService
Dim searchRequest
As New SearchRequest
Dim arraySize
As Integer = 1
Dim sr(arraySize)
As SourceRequest
sr(0) = New
SourceRequest
sr(0).Source
= [SourceType].Web
sr(0).ResultFields = ResultFieldMask.Title
_
Or ResultFieldMask.Url
sr(0).Count = 20
'assemble the search
string
Dim SearchText
As String = Me.Text & " "
If Me.SearchSiteOnly _
AndAlso
Me.SearchSite.Trim.Length > 0
Then
SearchText +=
" site:"
SearchText +=
Me.SearchSite
End If
'call the msn search
web service
searchRequest.Query = SearchText
searchRequest.Requests = sr
searchRequest.AppID =
Me.MSNApplicationID
searchRequest.CultureInfo =
"en-US"
Dim searchResponse
As SearchResponse
searchResponse = s.Search(searchRequest)
'fill a DataTable
with the results
Dim dt
As New DataTable
Dim dc
As New DataColumn("Title")
dt.Columns.Add(dc)
dc = New
DataColumn("Url")
dt.Columns.Add(dc)
Dim sourceResponse
As SourceResponse
For Each sourceResponse In
searchResponse.Responses
Dim
sourceResults As Result() = sourceResponse.Results
Dim
sourceResult As Result
For
Each sourceResult In
sourceResults
Dim dr As DataRow = dt.NewRow
dr(0) = sourceResult.Title
dr(1) = sourceResult.Url
dt.Rows.Add(dr)
Next
Next
Return
dt 'return the DataTable
End
Function
Figure 9: This function calls the
MSN Search Web Service, transforms the results into a DataTable, and returns the
DataTable.
After adding a Web reference to the MSN Search Web Service (located at
http://soap.search.msn.com/webservices.asmx?wsdl)
the code in Figure 9 should be able to successfully call the MSN
Search Web Service. The MSN Search Web Service is very rich in functionality, providing
a wide array of capabilities that are beyond the scope of this article. To learn
more about the MSN Search Web Service, download the MSN Search SDK, which includes
documentation and several well-commented sample applications.
Search Is King
I think you’ll find the SearchBox to be a valuable addition to your Visual Studio
toolbox. No longer will you need to write custom code to provide basic searching
functionality for your Web site. This functionality should work out of the box for
most public Web sites, but I can think of several nice enhancements for a future
version of the control. For example, you might add support for other search engines,
or you might choose to add a function to call Google’s search Web service. Another
option is to take advantage of MSN’s desktop search functionality, which may be
useful for Web sites that are not publicly available on the Internet (and therefore,
are unreachable by standard Web-based search engines). Google has certainly proved
that searching doesn’t have to be boring. The possibilities are endless, so let
your mind wander and see what you come up with.
The sample code in this article is available for
download.
This original version of
this article was published in
ASP.NET Pro
Magazine.