posted on Sunday, December 12, 2004 9:31 AM by anoras

How to create the Google Suggest feature with ASP.NET 2.0

Google Suggest seems to be the topic du jour in the blogosphere. It is a cool feature, but what I really enjoy is that it is yet another real world example of a “chubby” client.
I gave a presentation at an NNUG meeting at Microsoft’s Oslo office two months ago on how to create features akin to the auto-complete feature on display over at Google. In this article I will answer the question “everybody” is asking – How do did the guys at Google do that?

Out-of-band calls
It all started when Netscape released Navigator 2.0 in 1996. This browser boosted two revolutionary new features; frames and JavaScript. Although Netscape had different intensions for these features, developers could exploit frames and JavaScript to set up an out-of-band communications channel between the browser and the web server. This made it possible to update forms data without posting back. The concept behind the communications channel was simple. You created a frameset made up of two frames. One of the frames had the height or width attribute set to zero, in practice making the frame “invisible”. The other frame contained the user interface. When the user clicked a button she triggered a JavaScript function which replaced the location property of the hidden frame with the URL for a CGI script that handled the request. The various parameters were passed thru the query string.

top.RPCFrm.location.replace("RPC.cgi?CustomerId="+CustomerId.value);

When the page in the “hidden” frame was refreshed, the BODY element’s onload event was used to pass the result from the CGI script to a callback function.

function callback(result) {
    fields=result.split(',');
    Firstname.value=fields[0];
    MiddleName.value=fields[1];
    Surname.value=fields[2];
    Address.value=fields[3];
    PostalCode.value=fields[4];
    City.value=fields[5];
    Country.value=fields[6];
}

At the end of the 1990ies Microsoft introduced a technology called remote scripting. This was a combination of JavaScript helper methods, a proxy implemented as a Java applet and some ASP code which enabled you to do both synchronous and asynchronous calls from client side script to functions in server side ASP pages. Now developers could call server side methods via the Java proxy using the RSExecute method.

function LookUpBtn_onclick() {
    var callObject = RSExecute("RemoteScriptingFacade.aspx","GetCustomer",CustomerId.value);
    fields=callObject.return_value.split(',');
    Firstname.value=fields[0];
    MiddleName.value=fields[1];
    Surname.value=fields[2];
    Address.value=fields[3];
    PostalCode.value=fields[4];
    City.value=fields[5];
    Country.value=fields[6];
}

The above example shows a synchronous remote scripting method invocation. Remote scripting relied on Java, which is the key technology of Microsoft’s nemesis. On top of that even if the protocol was XML like, it was a proprietary protocol. Therefore when SOAP was introduced in 1998, Microsoft released the Web Service Behavior for Internet Explorer. The behavior leveraged the standardized SOAP protocol and Internet Explorer’s built-in XmlHttp support. As the name implies, the component enabled developers to invoke Web Service methods from JavaScript code. The example below shows how a Web Service can be invoked asynchronously from the browser.

function LookUpBtn_onclick() {
      WebService.facade.callService(callback,"GetCustomer",CustomerId.value);
}

function callback(result) {
    if (result.error) alert("WS Error:\nCode: "+result.errorDetail.code+"\nString:\n"+result.errorDetail.string+"\nRaw:\n"+result.errorDetail.raw);
    else {
        Firstname.value=result.raw.selectSingleNode("//FirstName").text;
        MiddleName.value=result.raw.selectSingleNode("//MiddleName").text;
        Surname.value=result.raw.selectSingleNode("//Surname").text;
        Address.value=result.raw.selectSingleNode("//Address").text;
        PostalCode.value=result.raw.selectSingleNode("//PostalCode").text;
        City.value=result.raw.selectSingleNode("//City").text;
        Country.value=result.raw.selectSingleNode("//Country").text;
    }
}

With the release of the .NET framework, attention shifted from browser based applications towards richer Windows Forms clients. Today, sophisticated web applications such as GMail, A9 and most recently Google Suggest has drawn attention to back to “chubby” clients combining some of the features in “fat” clients with the benefits of browser based applications. Microsoft is not by any means behind on this development. ASP.NET 2.0 has a new feature called script callbacks which relies on XmlHttpRequest to call back to the server.

public partial class Default_aspx : ICallbackEventHandler {
      private string callbackScriptBlock=String.Empty;
      public string CallbackScriptBlock
      {
            get
            {
                  return callbackScriptBlock;
            }
      }
      public void Page_Load(object sender, System.EventArgs e)
      {
            callbackScriptBlock = this.GetCallbackEventReference(this, "customerId", "showCustomerDetails", "context", "onError");
      }
      public string RaiseCallbackEvent(string eventArg)
      {
            Customer.Path = Server.MapPath("../Data/Customers.xml");
            Customer customer = Customer.Load(eventArg);
            return Customer.ToCsvString(customer);
      }
}

The above example shows how to create a page that implements the ICallBackEventHandler interface. Below are the JavaScript methods from the ASP.NET page.

function LookUpBtn_onclick() {
    var context="";
    var customerId=form1.CustomerId.value;
    <%= this.CallbackScriptBlock %>
}

function showCustomerDetails(result, context) {
    fields=result.split(',');
    form1.Firstname.value=fields[0];
    form1.MiddleName.value=fields[1];
    form1.Surname.value=fields[2];
    form1.Address.value=fields[3];
    form1.PostalCode.value=fields[4];
    form1.City.value=fields[5];
    form1.Country.value=fields[6];
}

The Google solution
All of the techniques above enable out-of-band communications between the browser and the server. The million dollar question is what is under Google Suggest’s hood?
First Google Suggest will try to instantiate Microsoft’s XmlHttp component using various references. If this doesn’t succeed an attempt is made to instantiate XMLHttpRequest. Microsoft first implemented the XMLHttpRequest object in Internet Explorer 5 for Windows as an ActiveX object. Engineers on the Mozilla project implemented a compatible native version for Mozilla 1.0. Apple has done the same starting with Safari 1.2. The XmlHttp or XMLHttpRequest object is used to make HTTP get requests to http://www.google.com/complete/search passing the text in the search field, the language and a JavaScript flag as query string parameters. Below is the response when searching for “XmlHttpRequest”.

sendRPCDone(frameElement, "xmlhttprequest", new Array("xmlhttprequest", "xmlhttprequest post", "xmlhttprequest javascript", "xmlhttprequest mozilla", "xmlhttprequest example", "xmlhttprequest send", "xmlhttprequest object", "xmlhttprequest php", "xmlhttprequest timeout", "xmlhttprequest firefox"), new Array("52,800 results", "6,010 results", "28,400 results", "15,900 results", "3,780 results", "8,860 results", "7,380 results", "46,100 results", "220 results", "10,500 results"), new Array(""));

As you can see, JavaScript code is returned. This code is executed using the eval method. Click here to submit a query for XmlHttpRequest to Google Suggest.
If Google Suggest was unable to create an XmlHttp or XMLHttpRequest instance it falls back to an “advanced” use of the oldest trick in the book; it dynamically creates an IFRAME which is used to phone home. The URL is the same as when using XmlHttp but the JavaScript flag set to false. Below is the response from a fallback request.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script>
function bodyLoad() {
  if (parent == window) return;
  var frameElement = this.frameElement;
  parent.sendRPCDone(frameElement, "xmlhttprequest", new Array("xmlhttprequest", "xmlhttprequest post", "xmlhttprequest javascript", "xmlhttprequest mozilla", "xmlhttprequest example", "xmlhttprequest send", "xmlhttprequest object", "xmlhttprequest php", "xmlhttprequest timeout", "xmlhttprequest firefox"), new Array("52,800 results", "6,010 results", "28,400 results", "15,900 results", "3,780 results", "8,860 results", "7,380 results", "46,100 results", "220 results", "10,500 results"), new Array(""));
}
</script></head><body onload='bodyLoad();'></body></html>

To achieve the super fast responses, Google does not perform an actual search every time a character is entered in the query field. Instead Google keeps an in-memory list of the most popular searches and returns suggestions from this list.

ASP.NET Suggest
The Google Suggest feature is fairly simple to implement using ASP.NET 2.0 script callbacks. The example is close to the one above with some minor differences. Instead of making an out-of-band call when the user clicks a button, a call is made every time the user enters a character in the search field. To do this you simply hook your remote method invocation stub to the onkeyup event on the INPUT element.

<input onkeyup="GetAutoComplete();" autocomplete="off" id="Query" type="text" size="40" />

You should also switch off the browser’s auto-complete feature; after all you don’t want it to compete with your far superior suggestion feature.
The RaiseCallbackEvent method in the code behind class should simple retrieve all popular searches starting with the same character sequences as the user’s current query.

public string RaiseCallbackEvent(string query)
{
      List<string> results = popularSearches.FindAll(delegate(string s)
      {
            return s.StartsWith(query);
      });
      StringBuilder sb = new StringBuilder();
      foreach (string result in results)
      {
            sb.Append(result);
            sb.Append(',');
      }
      sb.Append(' ');
      return sb.ToString();
}

The JavaScript callback handler then needs to display the relevant suggestions to the user.

function fillAutoComplete(result, context) {
    fields=result.split(',');
    form1.AutoComplete.value='';
    for (var i=0; i<fields.length; i++) {
        form1.AutoComplete.value+=fields[i]+'\n';
    }
}

I’ve chosen to do a rather naïve implementation of the suggestion feature to keep my sample easy to follow. To achieve a googlesque look, with all its bells and whistles, simply extend the above method to use some DHTML magic.

The complete source code can be viewed here: Default.aspx and Default.aspx.cs

Comments

# Carl swirled his tongue into her ***, letting it part her lips gently and then lifting it to &lt;a href=&quot;http://www.flovershop.info/youngblowjobs.html&quot;&gt;young blowjobs movies&lt;/a&gt; flick it over her *** then quickly @ Monday, May 21, 2007 8:12 AM

Derek

pushkin0612@rambler.ru

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Monday, May 21, 2007 11:43 AM

Sorry :(

Glafkos

# download free porn @ Tuesday, May 22, 2007 4:51 AM

<a href= http://honda-civic.moy.su/ >free porn</a>

free porn

# download free porn @ Tuesday, May 22, 2007 4:51 AM

<a href= http://honda-civic.moy.su/ >free porn</a>

free porn

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Tuesday, May 22, 2007 5:54 AM

Nice!

Odysseus

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Tuesday, May 22, 2007 7:51 AM

Cool.

Kris

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Tuesday, May 22, 2007 12:01 PM

Sorry :(

Ivan

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Tuesday, May 22, 2007 12:23 PM

Interesting...

Epameinondas

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Tuesday, May 22, 2007 12:45 PM

interesting

Xenophon

# cialis @ Tuesday, May 22, 2007 2:45 PM

<a href="http://uw-docs.uwyo.edu/ThePlan-HealthSciences/_comments/0000009f.htm#genericcialis">generic cialis</a>
<a href="http://uw-docs.uwyo.edu/ThePlan-HealthSciences/_comments/000000a0.htm#genericviagra">generic viagra</a>
<a href="http://uw-docs.uwyo.edu/ThePlan-HealthSciences/_comments/0000009d.htm#cialis">cialis</a>

cialis

# America is by design and practice, a polytheistic culture with many &lt;a href=&quot;http://www.sex-matrix.info/amatradrepair.html&quot;&gt;amateur radio repair&lt;/a&gt; held in check by the separation of church and state. By attem @ Tuesday, May 22, 2007 11:20 PM

Elliott

kolinovskiy@rambler.ru

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Tuesday, May 22, 2007 11:52 PM

Interesting...

Georghios

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Wednesday, May 23, 2007 2:39 AM

Nice

Agias

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Wednesday, May 23, 2007 3:50 AM

Cool...

Evripides

# On her way to her bedroom, Sara grasped Rebecca&amp;#039;s shoulder and gave a small squeeze. Rebecca looked up and was met with a sad smile. &lt;a href=&quot;http://www.tweeder.info/hotsexymat.html&quot;&gt;hot sexy mature babes&lt @ Wednesday, May 23, 2007 12:20 PM

Gregory

olegburnaev@rambler.ru

# I concentrated hard, the beer helping to slow me down, but I was nearly coming when she came with a cry, luckily drowned by the music.&lt;a href=&quot;http://www.asare.info/chubbyteen.html&quot;&gt;chubby teen boobs&lt;/a&gt; She st @ Wednesday, May 23, 2007 12:20 PM

Chester

krych3@rambler.ru

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Wednesday, May 23, 2007 2:18 PM

Nice...

Charilaos

# The blessing in this difficult experience is the powerful reminder that behind every business is a life - your life in &lt;a href=&quot;http://www.maxtits.info/daytona.html&quot;&gt;daytona bike week babes&lt;/a&gt;. It’s so easy to @ Thursday, May 24, 2007 4:59 AM

Malcolm

tatarov77@rambler.ru

# nother quick look at the list of factors that promote happiness shows that many things contribute to personal happiness; finding a balanced lifestyle so that you can include &lt;a href=&quot;http://www.clopclop.info/hardcsex.html&quot;&gt;h @ Thursday, May 24, 2007 5:49 AM

Harvey

mineeva2@hotmail.com

# This is an easy book to recommend: a thoughtful, thorough memoir by a writer with a subtle sense of humor and an easy-going way of expressing himself, filled with interesting characters, amusing anecdotes and some enlightening information - &lt;a href= @ Thursday, May 24, 2007 6:10 AM

Drew

zhumagulov2006@rambler.ru

# Another key to success is, to always keep looking for improvements in whatever we do. Life is an endless quest for efficiency: &lt;a href=&quot;http://www.adult-time.info/youngamatupskirt.html&quot;&gt;young amateur upskirt clips&lt;/a& @ Thursday, May 24, 2007 6:11 AM

Kyle

tatarov77@rambler.ru

# Watch these horny sluts taking it in the ass &lt;a href=&quot;http://www.badhotass.info/hottitsand.html&quot;&gt;hot *** and ass free&lt;/a&gt; for the first time and getting their virgin &lt;a href=&quot;http://www.badhotas @ Thursday, May 24, 2007 6:59 AM

Fred

fredssams@yandex.ru

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Sunday, May 27, 2007 7:44 PM

[url=http://easyfreeforum.com/adipex]adipex online[/url] <a href="http://163.32.124.4/ksml/board.asp?PG=P"> 124.4 </a> Great website, have a nice day <a href="http://www.118.lv/hockey06/?id=2731&amp;from=565&amp;PHPSESSID=2778446011d7985f3075060ec6cf334c#commentsForm"> 118.lv </a>

adipex online

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Sunday, May 27, 2007 7:45 PM

[url=http://easyfreeforum.com/adipex]adipex online[/url] <a href="http://163.32.124.4/ksml/board.asp?PG=P"> 124.4 </a> Great website, have a nice day <a href="http://www.118.lv/hockey06/?id=2731&amp;from=565&amp;PHPSESSID=2778446011d7985f3075060ec6cf334c#commentsForm"> 118.lv </a>

adipex online

# Sweet-sweet 18 &lt;a href=&quot;http://www.webcamteen.info/teenlesblov.html&quot;&gt;teen *** lovers&lt;/a&gt;! See thousands of pix and videos &lt;a href=&quot;http://www.webcamteen.info/teenthongs.html&quot;&gt;te @ Monday, May 28, 2007 1:13 AM

John

johnarebela@yandex.ru

# The risk of loss and title for items purchased by you pass to you upon the delivery of the items to the carrier &lt;a href=&quot;http://www.dooleko.info/freetoonsgaysexpubl.html&quot;&gt;free toons gay sex public&lt;/a&gt; In additi @ Monday, May 28, 2007 11:51 AM

Daddy

kolinovskiy@rambler.ru

# We got it all for you here – innocent &lt;a href=&quot;http://www.mydolls.info/blondepussybig.html&quot;&gt;Blonde *** Big Cocks&lt;/a&gt; and their first blowjob trainings, nasty whores under the mask of respectful business ladies @ Monday, May 28, 2007 1:15 PM

Jesse

baigozin2006@rambler.ru

# I am a beeutiful tortese-shell kittie with a fancy white stripe on my tail. I was taken in by my lady who found me wandering around a &lt;a href=&quot;http://www.bestmic.info/frenchfootjonwebc.html&quot;&gt;french footjob on webcams&lt; @ Monday, May 28, 2007 1:40 PM

Brett

serikbaev1@rambler.ru

# I can not change it to web service. It has to be a remoting component. And another constraint is, I need to have the shared interface method between the &lt;a href=&quot;http://www.love-teenie.info/karteengirlsteen.html&quot;&gt;karup tee @ Monday, May 28, 2007 4:51 PM

Zahid

alihanov1@rambler.ru

# I can not change it to web service. It has to be a remoting component. And another constraint is, I need to have the shared interface method between the &lt;a href=&quot;http://www.love-teenie.info/karteengirlsteen.html&quot;&gt;karup tee @ Monday, May 28, 2007 4:51 PM

Zahid

alihanov1@rambler.ru

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Monday, May 28, 2007 5:03 PM

<a href="http://motolanka.com/modules.php?name=Forums&file=posting&mode=quote&p=4519"> motolanka.com </a> http://carisoprodolz.forumlivre.com/">http://carisoprodolz.forumlivre.com/ Cheap carisoprodol [url]http://carisoprodolz.forumlivre.com/">http://carisoprodolz.forumlivre.com/[/url] <a href="http://engagedscholar.memphis.edu/home/index.php?page=ScholarPage"> memphis.edu </a> Google Webspam team

Cheap carisoprodol

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Monday, May 28, 2007 5:03 PM

<a href="http://motolanka.com/modules.php?name=Forums&file=posting&mode=quote&p=4519"> motolanka.com </a> http://carisoprodolz.forumlivre.com/">http://carisoprodolz.forumlivre.com/ Cheap carisoprodol [url]http://carisoprodolz.forumlivre.com/">http://carisoprodolz.forumlivre.com/[/url] <a href="http://engagedscholar.memphis.edu/home/index.php?page=ScholarPage"> memphis.edu </a> Google Webspam team

Cheap carisoprodol

# Jenna&amp;#039;s hot talk seemed to heat things up for both of us. Jill sucked me harder and deeper and I felt the jizz rising. &lt;a href=&quot;http://www.masturbatingays.info/malegaymass.html&quot;&gt;male gay massage&lt;/a&gt @ Monday, May 28, 2007 5:10 PM

Jorge

serikbaev1@rambler.ru

# Foreigners are threatening the sovereignty of &lt;a href=&quot;http://www.emptycom.info/softcplaym.html&quot;&gt;softcore playmates playboy classic&lt;/a&gt; and exploiting the people through the trade of opium and slave &lt;a h @ Monday, May 28, 2007 6:03 PM

Cliff

korzunov1@rambler.ru

# Foreigners are threatening the sovereignty of &lt;a href=&quot;http://www.emptycom.info/softcplaym.html&quot;&gt;softcore playmates playboy classic&lt;/a&gt; and exploiting the people through the trade of opium and slave &lt;a h @ Monday, May 28, 2007 6:03 PM

Cliff

korzunov1@rambler.ru

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Monday, May 28, 2007 6:41 PM

http://levitra.mobilblogg.no/">http://levitra.mobilblogg.no/ Buy Levitra [url]http://levitra.mobilblogg.no/">http://levitra.mobilblogg.no/[/url] hello, very nice site! please also visit my homepages <a href="http://www.anime-on-line.com/xcart/product.php?productid=10664&cat=17&page=1"> anime-on-line.com </a> <a href="http://www.aardvarkforms.com/product.php?productid=16357&cat=248&page=1"> aardvarkforms.com </a>

Buy Levitra

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Monday, May 28, 2007 6:41 PM

http://levitra.mobilblogg.no/">http://levitra.mobilblogg.no/ Buy Levitra [url]http://levitra.mobilblogg.no/">http://levitra.mobilblogg.no/[/url] hello, very nice site! please also visit my homepages <a href="http://www.anime-on-line.com/xcart/product.php?productid=10664&cat=17&page=1"> anime-on-line.com </a> <a href="http://www.aardvarkforms.com/product.php?productid=16357&cat=248&page=1"> aardvarkforms.com </a>

Buy Levitra

# My room was dark. My jeans were being removed; then my boxers. I lay there, completely exposed, before…who? Was that 3 hands I felt? Clad in only my shirt, I waited for my sister&amp;#039;s mouth on my ***. &lt;a href=&quot;http://www.gayorgyon @ Monday, May 28, 2007 7:26 PM

Patricia

grozniy6@rambler.ru

# re: How to create the Google Suggest feature with ASP.NET 2.0 @ Monday, May 28, 2007 7:49 PM

Great website, have a nice day <a href="http://www.aardvarkforms.com/product.php?productid=16357&cat=248&page=1"> aardvarkforms.com </a> http://valtrex1.iwannaforum.com/">http://valtrex1.iwannaforum.com/ buy valtrex [url]http://valtrex1.iwannaforum.com/">http://valtrex1.iwannaforum.com/[/url] <a href="http://www.anime-on-line.com/xcart/product.php?productid=10664&cat=17&page=1"> anime-on-line.com </a>

buy valtrex

# There was quite a lot of girls present, some food and some booze with dancing to record music. I sat down on a sofa and chatted to happy looking girls. &lt;a href=&quot;http://www.koloma.info/bustylesb.html&quot;&gt;busty lesbians anal& @ Monday, May 28, 2007 9:51 PM

Nick

mineeva2@rambler.ru

# A hot girl &lt;a href=&quot;http://www.shemaboys.info/nudeblack.html&quot;&gt;nude black ***&lt;/a&gt; with a big well-shaped penis. You will never regret watching these hardcore &lt;a href=&quot;http://www.shemaboys.info/br @ Tuesday, May 29, 2007 1:40 AM

Diana