oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Creating an Application from Scratch, Part 3
Pages: 1, 2, 3, 4, 5

FindBookInfo works much the same way except that I use an ItemLookup object rather than a CustomerLookup object.

ItemLookup itemLookup = new ItemLookup();
ItemLookupRequest itemLookupRequest = new ItemLookupRequest();
ItemLookupResponse itemLookupResponse;
itemLookup.AssociateTag = this.associateTag;
itemLookup.SubscriptionId = this.subscriptionID;
foreach ( Book theBook in myBooks )
   pageNumber = 1;
   totalPages = 1;

   while ( pageNumber <= totalPages  )
      itemLookupRequest.ItemId = new string[] { theBook.ASIN };
      itemLookupRequest.ReviewPage = pageNumber.ToString();
      itemLookupRequest.ResponseGroup = new string[] 
            { "Small", "Reviews", "ItemAttributes" };
      itemLookup.Request = new ItemLookupRequest[] { itemLookupRequest };
         itemLookupResponse = amazonService.ItemLookup( itemLookup );
      catch ( Exception ex )
         lblMessage.Text = ex.Message;

Here I iterate through all the books I've reviewed, and for each one I make a request, setting the ItemID to the ASIN for the book. The ResponseGroup is important, as this tells the Amazon web service which information I want about the particular book.

  • The Small response group provides the URL to the book listing
  • The Reviews response group provides all the reviews by all reviewers
  • The ItemAttribute response group provides item-specific information such as author, publisher, etc.

Once I have the item response (that is, the information about each book I've reviewed) I can drill down to get the book info and insert that information into the database (see "Book Table Design Question" above).

Items[] itemsArray = itemLookupResponse.Items;
if ( itemsArray.Length > 0 )
   Item[] itemArray = itemsArray[0].Item;
   if ( itemArray.Length > 0 )
      CustomerReviews customerReviews = itemArray[0].CustomerReviews;
      if ( customerReviews != null )
         if ( pageNumber == 1 )
            totalPages = Convert.ToInt32( customerReviews.TotalReviewPages );
            string url = itemArray[0].DetailPageURL == null ? 
               string.Empty : itemArray[0].DetailPageURL;
            string title = itemArray[0].ItemAttributes.Title == null ? 
               string.Empty : itemArray[0].ItemAttributes.Title;
            string author = string.Empty;
            if ( itemArray[0].ItemAttributes.Author != null &&
               itemArray[0].ItemAttributes.Author[0] != null )
               author = itemArray[0].ItemAttributes.Author[0];
            InsertBook( theBook.ASIN, title, url, author );

That done, I can now get all the reviews for the book (that is, the reviews by other reviewers) and for each one found, I compare my rating to theirs, and update the reviewer in the allReviewers collection.

// find everyone who has reviewed this book
Review[] reviewArray = customerReviews.Review;
foreach ( Review theReview in reviewArray )
   string reviewerID = theReview.CustomerId;
   if ( reviewerID != myReviewerID )  // note me?
      int score = 0;
      try  // make sure you have integral ratings (as you should)
         int myRating = Convert.ToInt32( theBook.MyRating );
         int theirRating = Convert.ToInt32( theReview.Rating );
         score = 5 - ( System.Math.Abs( myRating - theirRating ) );

         if ( allReviewers.ContainsKey( reviewerID ) )
            allReviewers[reviewerID].Score += score;
            allReviewers.Add( reviewerID, new Reviewer( reviewerID, score ) );
         this.lblInformation.Text = "Reviewers: " + allReviewers.Count.ToString();
      catch ( Exception ex )
         this.lblMessage.Text = "Unable to add reviewer " + reviewerID + ex.Message;
   }  // end if not me
}     // end for each review

It is possible to ask for ten items (books) at a time, and that is an obvious opportunity for optimization, though it will slightly complicate the loop.

Once we've found all the reviews for all the books I've reviewed, the collection allReviewers has the ID of every Amazon customer who has reviewed any books I've reviewed. We then pass that back to FindReviewers, and iterate through the list, getting all their reviews of all the books they've ever reviewed, and setting their score if I've reviewed the book as well. The end point is that I have a list of reviewers with scores for how well they match my taste, and a list of other books they've reviewed and how they rated those books. That is all I need to find books highly rated by readers who agree with my ratings of books we've both rated!

The complete source for this application is available on my web site; just click on Books and then on Articles.

Jesse Liberty is a senior program manager for Microsoft Silverlight where he is responsible for the creation of tutorials, videos and other content to facilitate the learning and use of Silverlight. Jesse is well known in the industry in part because of his many bestselling books, including O'Reilly Media's Programming .NET 3.5, Programming C# 3.0, Learning ASP.NET with AJAX and the soon to be published Programming Silverlight.

Read more Liberty on Beta 2 columns.

Return to