FREE hit counter and Internet traffic statistics from freestats.com

Tuesday, January 27, 2004

Amazon.com and the .NET Compact Framework

I recently downloaded the developer's kit from Amazon.com to take a look at how their web services are structured. I quickly discovered that it is quite simple to get an app up and running that queries the Amazon catalog. The SDK has some fairly complete documentation and includes several different samples to get you going.

Being familiar with the .NET Compact Framework created a VS .NET project in VB .NET to browse the catalog given a set of ISBNs. By creating a web reference to the Amazon web services WSDL doc (http://soap.amazon.com/schemas3/AmazonWebServices.wsdl) VS .NET created the proxy and associated classes from the XSDs to work with the data returned by the web service - some 58 classes in all.

The primary class you use to search the catalog are the various request classes such as AsinRequest. Each request class encapsulates the parameters of the request which you pass to methods of the AmazonSearchService class. Types of requests include searching by Asin (Amazon standard item number, in this case ISBN), Author, Artist, Director, Keyword, ListMania, Marketplace, Seller, Wishlist etc. In my application I provided a list of Asins in a text file that the app reads at startup. The AsinRequest is then created as follows:

Dim ar As New com.amazon.soap.AsinRequest

ar.asin = isbnList
ar.devtag = "D44NOTMYREALDEVTAG" 'per developer
ar.mode = "books"
ar.type = "heavy"
ar.tag = "webservices-20"

The properties determine how the request will be fullfilled. In this case my list is in a string variable isbnList, my developer tag assigned by Amazon when you register to download the SDK, the search mode (the kind of info returned, e.g. music, dvd), the type of search determining how much data is returned, and the tag which I believe represents the version.

To actually perform the search you simply need to instantiate the AmazonSearchService and pass the AsinRequest to the AsinSearchRequest method.

Dim s As New com.amazon.soap.AmazonSearchService

Dim p As com.amazon.soap.ProductInfo
Dim details() As com.amazon.soap.Details

Try
p = s.AsinSearchRequest(ar)
details = p.Details
LoadView()
Catch
MsgBox("Could not refresh the list.")
End Try




The ProductInfo class contains an array of Details objects that include the detail for each item. In my app I read the titles into a ComboBox and then present some of the data when the user selected a different item.
Dim d As com.amazon.soap.Details


For Each d In details
cbTitles.Items.Add(d.ProductName)
Next

...

lblISBN.Text = details(index).Isbn
lblAPrice.Text = details(index).OurPrice
lblUPrice.Text = details(index).UsedPrice
lblSRank.Text = details(index).SalesRank
If Not details(index).Reviews Is Nothing Then
lblReviews.Text = details(index).Reviews.TotalCustomerReviews
lblStars.Text = details(index).Reviews.AvgCustomerRating
Else
lblReviews.Text = "0"
lblStars.Text = "N/A"
End If


Perhaps the most interesting aspect of the application, however, is displaying the image for the book. The Details object includes three Urls for the small, medium, and large images. I wrote a small function to download the image on demand and place it in an ImageList control for later reference.



Private Function GetImage(ByVal url As String) As Boolean
If net.IsConnected Then
Try
Dim wr As HttpWebRequest = HttpWebRequest.Create(url)
' Wait 4 seconds and then give up
wr.Timeout = 4000
Dim resp As HttpWebResponse = wr.GetResponse
Dim b As New Bitmap(resp.GetResponseStream)
ImageList1.Images.Add(b)
resp.Close()
imageIndex.Add(url)
Return True
Catch e As Exception
' Skip it
Return False
End Try
Return False
End If
End Function


In order to track if the image had already been downloaded I simply used an ArrayList (imageIndex) and searched on the Url when attempting to load the image.



Dim i As Integer
' See if its in the index
i = imageIndex.IndexOf(details(index).ImageUrlSmall)
If i = -1 Then
' Not so try and get it
GetImage(details(index).ImageUrlSmall)
End If
' Go get the index
i = imageIndex.IndexOf(details(index).ImageUrlSmall)
If i > -1 Then
' Load if there else ignore
pbBooks.Image = ImageList1.Images(i)
Else
pbBooks.Image = Nothing
End If


The final application looks as follows.

I also wrote a small form to manage the list of ISBNs so the user would be able to add new ones.

Anyway, an interesting little exploration that could be used to write "just in time" style apps for booksellers and collectors as they browse used bookstores. Of course, you can also purchase through the web services interface as well as track your items if you're a seller.

No comments: