Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Amazon Explorer - An adventure with ASP.NET & the Amazon Web Service

0.00/5 (No votes)
27 Aug 2003 1  
Create an ASP.NET application that uses the Amazon Web Service to search the Amazon catalogs.

Sample Image - amazonportal.jpg

Introduction

Since the advent of the .NET framework and Web Services I've heard of many interesting and wonderful applications of the two technologies. However, you never really get an appreciation for something until you actually try it yourself. Well, I tried out these technologies with an idea of mine and I must say that it has turned out quite well and was not that difficult to implement. I now introduce to everyone my first ASP.NET application, The Amazon Explorer.

In a few words, the Amazon Explorer is an ASP.NET application that allows the user to search Amazon for any item in their catalogs by utilizing the Amazon Web Service (version 3.0).

How to setup/install

I used a Web Setup project to create the installer for Amazon Explorer in Visual Studio .NET 2002. Simple run the AmazonPortalSetup.msi and follow the instructions. You will need to have IIS running. The Setup creates a virtual directory in IIS and copies the files (source, DLL, etc ..) to your hard drive. Alternatively you can create an ASP.NET application from the Visual Studio templates then copy the source files from the zip file provided.

The adventure - lessons learnt

During the construction of this application I learned about the various capabilities and functionality offered by the .NET framework that take the pain out of web development and allow for easy usage of Web Services. I'll go through each of the useful features of ASP.NET and the .NET framework along with the functionality of the application in this section.

The user interface (UI)

The Amazon Explorer interface is a basic one that seeks to capture all necessary input from the user in an elegant and simple form. Below you can see screenshots of when the application is initially launched and one of the application displaying results from a previous search:

Figure 01: Initial application interface

Figure 02: Results page

For the lifetime of the application, these two screens are what you will come to see. The only exception being if an error occurs during the search, at which time you will see an appropriate error message displayed. The interface is a simple one and contains just a few ASP.NET Web Form controls. When I first started this application, I had used normal HTML versions of the Web Form controls you see, namely, Drop-Down lists, text boxes, and a submit button.

The problem here was that I was not able to keep the values of the controls across submissions of the form used in the application my default! Sigh ... but not for long, Web Forms came running to my rescue :). I discovered that Web Form controls were capable of retaining their values, by default, across submissions. My first thought ... beautiful! From this point, I replaced all the normal HTML controls with their respective Web Form control versions. Below you can see a shot of the UI as it is in the Visual Studio .NET IDE:

Figure 03: Visual Studio .NET IDE -- Design mode

In Figure 03 above, you will note the numbers 1 -3. Each of these areas contain different controls or components that comprise the entire Amazon Explorer application.

Area 1: DataGrid component

The DataGrid component is used to display the results of a search by the end-user. This component is quite ideal for the job as it can be bound to various data sources. The data source used is really dependent on your needs, but for this scenario I used a DataSet. The data source for the search is populated via the Amazon Web Service.

Area 2: Drop-Down lists, text boxes, and submit button

Drop Down lists were used to accommodate the easy selection by users of search parameters that aided in the search for the item in the Amazon catalog. One drop-down list was used to allow the user to select the category they think their item will be found in. The other list allows the user to specify the maximum number of results they want the search to produce on the results page.

Text boxes were used to gather loose (i.e. typed) input from the users. Specifically, I wanted to get the name of the item that the user wanted to search for. The other text boxes, I use to collect price range values so that the user can search for an item in a price range. Unfortunately the Amazon Web Service does not support price ranges via SOAP but do support it via normal HTTP requests. In the future when SOAP support exists, these text boxes will be used in the back-end but for now I leave them to display the validation features of ASP.NET Web Form controls.

Area 3: Validator controls

Validator controls are used to help validate user input before the form values are used to commit a search against the Amazon Web Service. These controls surprised me with their simplicity! Usually in the older days one would have to write JavaScript to do input validation and verification. Although there are masses of reusable code to do this on the web, it would still be nice to just specify simple rules for the validation and let .NET take care of the rest. Well, like I've been told in the past, ask and you shall receive.

To perform input validation here, I used the .NET CompareValidator Web Form control which quite nicely allows you to specify the items to be compared by just choosing them in the properties of the control. How sweet is that! Along with this nice feature, to specify an error message, you simply type it into a property field and voila you have yourself very nice and simple input validation on your Web Form.

Figure 04: CompareValidator property sheet

That pretty much took care of my user interface. The only extra is that I changed the format of the DataGrid using its property sheet to give me a nice looking color scheme for the DataGrid display. Everybody should remember this color scheme from Microsoft Word's Table AutoFormat option.

The Back-End (Code behind)

So now that we have a UI we need some code that processes the input from our UI to give us some meaningful output by means of displaying some results to the end-user. My implementation language of choice in this project is C#. Why one may ask? Well the .NET framework gives me the flexibility to implement this application in any of 30+ plus languages that it supports but for historical reasons, I like my curly braces and semi-colons :)

Initially when I started this project I thought I would have a lot of code to write. Boy was I wrong. The action starts in Amazon Explorer when the user clicks the "Search Amazon" button. The Web Form is sent back to the server where the input is gathered and run thru the Amazon Web Service which then returns some results to the Web Form for display to the user. That's it in a nice tight nutshell. All code for gathering the input from the text Boxes to processing the click of the Search button are in the back-end. Along with that however, we have several neat features offered by .NET.

Gathering & caching data

Amazon Explorer's main purpose is displaying results from a end-user search. As one can imagine there are times when there will be LOTS of results. A nice way to solve this issue is to have a mechanism to page the results displaying "x" results at a time. The DataGrid offers this functionality with the simple selection of a few property fields of the control. The fields involved in this are namely, AllowPaging and PageSize. Note also that you can implement your own custom paging solution for the DataGrid, however, I just wanted simple paging so I went with the property selections. Along with these property selections, one also has to create an event-handler for the PageIndexChanged event which is fired by the DataGrid when a user selects a different page than the current page.

1: private void gridAmazonResults_PageIndexChanged
                    (object source, DataGridPageChangedEventArgs e)
2: {
3:    gridAmazonResults.CurrentPageIndex = e.NewPageIndex;
4:    dsetAmazonReponse = (DataSet)Cache[AMAZON_CACHE_NAME];
5:    gridAmazonResults.DataSource = dsetAmazonReponse;
6:    gridAmazonResults.DataBind();
7: }

It is important to note here that all that is being done is to change the current page index in the DataGrid (line 3) and then bind the DataGrid (line 6) to a cached DataSet (line 4-5).

Caching in ASP.NET is quite simple and shows remarkable speed increases in terms of usability and processing of data. Initially when I was performing paging without caching, each page change required a hit to the Amazon Web Service for the page to be updated even though I already had all the information in the DataSet used in the application. Of course you can imagine the performance issues with this. The reason I use caching in the application, apart from the performance improvement, is that when a user does a search, it is better to allow him to view all the results returned at the time of his search. We only hit the Amazon Web Service again when the user clicks the "Search Amazon" button which indicates that he wants to perform a "brand new" search instead of looking at all his results.

1: private void btnSubmit_Click(object sender, System.EventArgs e)
2: {
3:   Cache.Remove(AMAZON_CACHE_NAME);
4:   dsetAmazonReponse = (DataSet)Cache[AMAZON_CACHE_NAME];
5:
6:   if( dsetAmazonReponse == null )
7:   {
8:      dsetAmazonReponse = new DataSet();
9:      dsetAmazonReponse.Tables.Add("AmazonResults");
10:     dsetAmazonReponse.Tables["AmazonResults"].Columns.Add("Preview");
11:     dsetAmazonReponse.Tables["AmazonResults"].Columns.Add("Name");
12:     dsetAmazonReponse.Tables["AmazonResults"].Columns.Add("Our Price");
13:     dsetAmazonReponse.Tables["AmazonResults"].Columns.Add("List Price");
14:     dsetAmazonReponse.Tables["AmazonResults"].Columns.Add("Catalog");
15:        
16:     ProcessSearchRequest();
17:     Cache[AMAZON_CACHE_NAME] = dsetAmazonReponse;
18:   }
19:   dsetAmazonReponse = (DataSet)Cache[AMAZON_CACHE_NAME];
20:   gridAmazonResults.DataSource = dsetAmazonReponse;
21:   gridAmazonResults.DataBind();
22: }

In the above code extract we see what's going on when a user requests a "brand new" search. We first remove the current DataSet that is in the cache (line 3-4) then we acquire a new DataSet and create the table we use to setup the data we get from the Amazon Web Service (line 6-18). After the request has been performed by the Amazon Web Service we rebind our DataGrid to the DataSet that now has the data we want to display in the grid to the user in a nice formatted manner (line19-21).

Application configuration

Like most applications, Amazon Explorer has certain characteristics that can be configured to affect how the application runs. One such example is the configuration that allows the application to be run behind a proxy. I wanted a mechanism that would allow me to change a flag or something to that effect to allow Amazon Explorer to work behind a proxy without me having to recompile code and all that fun stuff. Again, the .NET framework came through for me.

Microsoft has a mechanism which now allows developers to put their application specific settings in what they called .config files. Really and truly, these files are quite similar to .ini files with the only difference being that they are in XML format. Well with this nice feature, I was able to specify a few settings that would change as the application was distributed to various domains, machines, and developers.

<appSettings>
   <add key="SetProxy" value="off" />
   <add key="ProxyIP" value="111.2.3.4" />
   <add key="ProxyPort" value="8080" />
</appSettings>

Above I am able to specify in the Web.config file some properties that I consider dynamic in the application. The proxy information allows me to change the proxy information for my location just by editing the .config file. When the user click the "Search Amazon" button again, the proxy will be used depending on the value of the SetProxy field in the .config file.

1: private void Page_Load(object sender, System.EventArgs e)
2: {
3:   if( ConfigurationSettings.AppSettings[CONFIG_PROXY_NAME] == "on" )
4:    SetProxy(ConfigurationSettings.AppSettings[CONFIG_PROXY_IPVALUE],
5:      Convert.ToInt32(ConfigurationSettings.
6:                   AppSettings[CONFIG_PROXY_PORTVALUE]));
7: }

In line 3 of the above code, you can see how we access the settings specified in the .config file from the Web Form code. The AppSettings collection of the Configuration object contains all the key-value fields we specified in the <appSettings> element of the XML based .config file. Gaining access to the values of the settings is a simple matter of indexing into the AppSettings array and voila, you have your dynamic settings now loaded into your application.

The Amazon web service

The real work horse of the application is the Amazon Web Service. Without it, we would have no results to display. The Amazon Web Service API is quite simple and only requires a few lines of code to allow the developer to request a query and receive a collection of items. A sample piece of code to perform a general keyword search on Amazon's catalogs is as below:

1: AmazonSearchService amazonSrch = new AmazonSearchService();
2: KeywordRequest kwdReq = new KeywordRequest();
3:
4: kwdReq.devtag = "1010101010";
5: kwdReq.keyword = "Beenie Man";
6: kwdReq.type = "heavy";
7: kwdReq.mode = "music";
8:
9: ProductInfo prodMfg = amazonSrch.KeywordSearchRequest(kwdReq);

The three key objects are AmazonSearchService, KeywordRequest, and ProductInfo. The name of the objects alone give you an idea of their purpose in the whole scheme of things. The AmazonSearchService is what we use to connect to the Web Service offered by Amazon. Through this object we can perform various types of searches/requests as provided by the API. One such type search/request is the KeywordRequest which allows us to do a search of the Amazon catalog by simple providing a keyword, quite similar to how one searches a regular web search engine like Google. Each of the various requests offered by the API returns some form of product information regarding the item(s) it found in the catalog. This information is encapsulated in the ProductInfo object. The ProductInfo object itself contains a collection of Details objects. Each Details object in the collection - an array - contains the specifics on an item found in the catalog. I will leave it to you to discover these specifics on your own because it is quite a lot!

Each time that we get some product information, we want to make that information available to our DataGrid so that it can be displayed to the end-user during their viewing of the results. We do this by adding the information to our DataSet which will later be bounded to the DataGrid.

1: private void AddToDataSet(ProductInfo newProducts)
2: {
3:    DataRow newRow;
4:
5:    for( int i = 0; i < newProducts.Details.Length; i++ )
6:    {
7:       newRow = dsetAmazonReponse.Tables["AmazonResults"].NewRow();
8:
9:       newRow["Our Price"] = newProducts.Details[i].OurPrice;
10:      newRow["List Price"] = newProducts.Details[i].ListPrice;
11:      newRow["Catalog"] = newProducts.Details[i].Catalog;
12:
13:      dsetAmazonReponse.Tables["AmazonResults"].Rows.Add(newRow);
14:   }
15: }

As you can see above, every new item is placed in a new row of our DataSet (line 13) and the columns of the row are populated with the actual data from the Details object (line 9-11). At the end of this method we would have collected all the product information we need to display to the user. When you look at the actual code you will see ways that you can modify and format the data as you wish. The above code is just a simple example.

Conclusion

From idea to reality, this application was done in about a week and a half on and off and with no prior knowledge of ASP.NET. That to me, is quite impressive and tells me that Microsoft has taken a step forward in their mission to help developers get things done quickly, but efficiently. I personally now have a lot of interest in the ASP.NET and Web Services and look forward to doing more work with both technologies. As you can see, the Amazon Web Service API is quite simple and not hard to use and ASP.NET itself is not difficult to use either as it provides powerful functionality in a simple interface via elegant controls and components.

Resources

Here is a list of resources I found very useful while developing and researching this application.

Revisions

  • 08-28-2003:
    • Original article submitted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here