Google Mini images in results ASP.NET

Providing search for our ASP.NET site has been left to an implementation of the Google Mini. This choice was for speed of set up, user familiarity with result sets generated and the fact that Microsoft Search was not released when the decision was made. The Google Mini is a 1U high rack mount server hardware supplied by Google. It provides a web browser administrator interface and lets you integrate it into your site in a few different ways. We fire requests to it and get an XML results file back that we then manipulate to produce a good search experience. We use the GSALib port of the gsa-japi Jarva library.

Now we have it up and running it has now become time to start tinkering a bit to try and get better results. The first challenge was getting product image thumbnails shown next to the search results from the Google Mini. This actually was very simple to achieve. The Mini understands meta tags in your html. If you put the following into the <head></head> section of the product pages:
<meta name="tw-prodimg" content="48350_01.jpg" />
Then then when the mini indexes your pages, this tag together with any others present, will be stored as a collection against that page’s result. You must explicitly ask for the meta tags to be included in the XML results from the Mini if you wish to consume them in the resulting XML from the search appliance.

   1: Dim objQuery As New GSA.Query
   2: Dim collections(0) As String
   3: collections(0) = _searchSiteCollection
   4: objQuery.setSiteCollections(collections)
   5: objQuery.setFrontend(_searchFrontEnd)
   6: objQuery.setOutputFormat(GSALib.Constants.Output.XML_NO_DTD)
   7: objQuery.setOutputEncoding(Constants.Encoding.UTF8)
   8: objQuery.setAccess(Constants.Access.PUBLIC)
   9: objQuery.setScrollAhead(CInt(_searchStartPageIndex))
  10: objQuery.setMaxResults(_searchPageSize)
  11: objQuery.setFilter(_searchFilter)
  12: 'Set set FetchMataFields=* to get all meta tags associated with page result
  13: Dim o As String() = {"*"}
  14: objQuery.setFetchMetaFields(o)


As you can see a call to setFetchMetaFields has been passed “*” this means return all meta tags from this pages result. You may if you prefer pass a string array of meta tags you are interested in seeing to reduce the returned tags. You may also use meta tags for filtering result sets by meta tag, but not part of this discussion.

Now  the results will include an XML node <MT> that contains the meta tags, this is exposed through the GSA library as a string collection hanging off the search page result it is associated with. Thus we can now show the image on the page using data binding in our repeater control, thus:

<asp:HyperLink ID="sImgLnk" NavigateUrl='<%# Server.HtmlDecode(eval("Url")) %>'
  runat="server" meta:resourcekey="HypImageResource2"></asp:HyperLink>:HyperLink>
   1: Protected Sub repeaterProductResults_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles repeaterProductResults.ItemDataBound
   2:     If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then
   3:         Dim SearchResult As GSA.Result = CType(e.Item.DataItem, GSA.Result)
   4:         If SearchResult.Metas.Contains("tw-ItemImg") Then
   5:             DirectCast(e.Item.FindControl("sImgLnk"), HyperLink).ImageUrl = ConfigurationManager.AppSettings("PathToProductThumbs").ToString & SearchResult.Metas("can-ItemImg")
   6:         Else
   7:             DirectCast(e.Item.FindControl("sImgLnk"), HyperLink).ImageUrl = ConfigurationManager.AppSettings("PathToProductThumbs").ToString & "noimage.gif"
   8:         End If
   9:     End If
  10: End Sub


Thus you now have item images against the items. You can obviously expand this so that all your pages could have a “searchimage” meta tag so that news items or other content could all have individual thumbs.

Publishing Catalogue Management System to ASP.NET

Project complete

Finally there has been a window of opportunity to get the CMS->Web application complete.

Read my write up of what  I’ve been up to with it here.

It uses WCF, LINQ to objects and a smart client windows forms application to publish item information from the catalogue management system in Quark Xpress format Oracle binary fields to a SQL server driven ASP.NET website.

This is version one and as always there are already some ideas on how it could be used to improve the experience of the site visitors. Already I’ve changed it to hot link product  codes and “see index” to a search shortcut.

To be honest, I’m just glad that finally I have put this one to bed. From Delphi to .NET it has been many years sitting on floppy disks on the shelf but finally it is born to generate some more turnover that in the current environment has to be a good thing. It should also be a spring board to offering even richer information on the site!

Read about in part 1.



Since ASP.NET 2.0 I’ve always liked the accessible way that caching has been presented to the ASP.NET developer. There are a number of good options for improving your server performance through server caches that are all really easy to get your head around and simple to implement in their most basic form.

Digging deeper into the cache

Like with most aspects of development when one looks more closely find it can get much more complex in order to optimise caching to your particular site heuristics.

The caching on the ecommerce site I’m working on at the moment was mostly removed during a site revamp last year, with the intention to put it back in again. Some of the new features I’m writing at the moment would be hit hard after a monthly email shot, thus caching is very attractive for these pages. Thus I ended up reminding myself of my options.

The site has a grid containing up to a thousand products and prices to show to the site visitor. The view of these items had to have the following features;

  • Ability to sort the grid
  • May filter the items viewed
  • Can page the results with variable items per page
  • Items in grid take context of current user language and currency selection

Page caching is not really helpful, instead I’m best caching the IEnumerable class that represents the items in the grid.

Watch out for bad performance behaviour

The thing you have to remember about web pages is that multiple users may be accessing the same page at the same time. This means you have to be a bit defensive about how you cache the object. I know the object take a long time to build as it comes from a database query that is quite intensive and some post query processing that takes a bit of time too, thus it is very realistic to see that if three users hit the page in quick succession when the cache is empty, they will all see it as empty and all simultaneously try to populate the cache, overwriting each other as they reach completion and write to the cache. Obviously this is going to load the application and database unnecessarily.

Reading around the subject I found the good old singleton pattern is a good one to start of using. If you’ve been through the joy of multithreaded applications you will know about Lock or SyncLock in vb. This allows you to lock a section of code so that only one thread may be running that section at any time. The other threads  are blocked indefinitely waiting for the lock to clear. Well if you use a lock on the cache refresh, obviously the other users  hitting the page will have to wait for the cache to be refreshed until they can move on and read from it.


The other one to watch out for out there that I noticed while reading up was many code examples for using the cache that forget that the item may drop out of the cache at any moment. So if you check the object exists in the cache, you need to grab it at the same time as next time you go to fetch it, it may have dropped out and nothing will be returned.

Got the cache working then used LINQ to Objects to get the paging and filtering working, what a joy to do, I’m really getting into LINQ!

ASP.NET Comparing large website directory trees

Windiff Directory comparison tool, by Mircosoft

It is always great to discover utilities that already exist on your machine.
Yesterday I wanted to compare two directories trees containing thousands of directories to see what had changed between two computers. I was trying to resolve a source control error for a big ASP.NET website.

In this case I was not looking for anything complicated merely what changes there are between the machines. In the past I’ve tried downloads from the internet that are utilities that do all sorts of interesting stuff in comparing files and directories. However I didn’t have any of these installed on the machine I was using. I then uncovered Windiff.exe.

Find it

In Microsoft Windows 2000 and later, Windiff.exe is included on the original CD-ROM in the Support\Tools folder details of how to use it can be found here: . It is a windows forms driven application that shows in two columns what has changed between the two directories and allows the user to drill down into the files listed to look at the differences within those files too.

Windiff Comparing Two Directories shows differences in red
Use it

The application also allows editing of those file too. Very, very useful. So after going into the vista start>Start Search I typed windiff and was away. Compared the directories, found my missing files and job done.
It happens so rarely that a job ends up simpler that you thought, so its woth blogging about when it happens!