Thanks to a commenter on this blog for pointing out that my original try at signing Amazon requests was based on incorrect information. Turns out that adding a certificate to your requests to the Amazon Advertising API does not actually "sign" the requests. The API still expects the AWSAccessKey, Timestamp and computed Signature in the SOAP headers.
The only way to do this is by using WCF to connect to the web service. Unfortunately, this does require adding a reference to the latest version of the Amazon API. I was hoping to continue to use the older version indefinitely, but it doesn't appear there's a way to sign requests while still using an older version of the web service.
So I had to bite the bullet on this one and upgrade, but the good news is that the latest version appears to be fully backward compatible with the old version. Except for a few lines of code to sign the requests, I didn't have to change any of my code to use the new version, but your mileage may vary.
NOTE: The bulk of this blog post was taken from a very helpful post on this site: http://flyingpies.wordpress.com/?p=17, written by Oren Trutner. My contribution is really just to port his code over to VB.NET because that's the primary language of my site.
So here's what you need to do if you're running an older version of the Amazon ECS service, and you need to sign your requests.
First, make sure you have your access identifier key and your secret key for Amazon Web Services, which you can find on http://aws.amazon.com/. These two keys are located on your Access Identifiers page, as shown below.
Second, you need to add a reference to the latest version of the Amazon Advertising API. You do this by right-clicking on the project and selecting "Add Service Reference…" (Do not select the "Add Web Reference" item.) Then enter the address http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl and click Go.
Enter a name for the service reference and hit OK (I called it "AmazonECS2009" to differentiate it from the old, WSE reference, which was "AmazonECS").
The code I got from Owen Trutner's blog features three classes that inherit/implement WCF classes to allow for signing of the request. There's AmazonHeader, which inherits from System.ServiceModel.Channels.MessageHeader. There's AmazonSigningEndpointBehavior, which implements System.ServiceModel.Description.IEndpointBehavior. Finally, there's AmazonSigningMessageInspector, which implements the System.ServiceModel.Dispatcher.IClientMessageInspector interface. All three of these code files can be found in the zip file at the end of this article.
Take these files and include them in your App_Code directory. Now you'll have to change your requests that import the old web reference to import the new, like so:
'Imports AmazonECS
Imports AmazonECS2009
Now, modify your calls to the AWSE service to use the WCF client. Here's what my code looked like before making the change:
Dim oCommerceServ As
New AWSECommerceService()
Dim oItemLookup As
New ItemLookup()
oItemLookup.SubscriptionId = "XXXXXXXXXXXXXXXXXXXX"
oItemLookup.AssociateTag = "MyAssociateId-20"
Dim oLookupRequest As
New ItemLookupRequest()
Dim oLookupResponse As ItemLookupResponse
'Set the search parameters
oLookupRequest.ItemId = New
String() {sAsin}
oLookupRequest.ResponseGroup = New
String() {"Small", "Images", "ItemAttributes", _
"OfferFull", "EditorialReview", "Reviews"}
oLookupRequest.ReviewSort = "-HelpfulVotes"
'Most helpful review first
'Assign the request to the item search object
oItemLookup.Request = New ItemLookupRequest() {oLookupRequest}
Try
'Send the query
oLookupResponse = oCommerceServ.ItemLookup(oItemLookup)
Catch oException As Exception
<Error Handling Code>
End
Try
More...