Signing Amazon Product Advertising API requests — the missing C# WCF sample

(See also part 2 of this post)

Just the sample code

Download the sample project from:

AmazonProductAdvtApiWcfSample.zip, 324KB, 8/1/2009

The sample is self-contained. You don’t need to follow any of the text in this post to build and use it. If trying to replicate the sample’s behavior in a different program, take a look at step 2 below regarding adding the Amazon ECS service reference.

Authentication of Product Advertising API requests

If you develop for the Amazon Product Advertising API (formerly known as the Amazon Associates Web Service — AWS), you would have noticed by now the repeating emails from Amazon about a change in the rules. Starting August 15, 2009, all API requests must be authenticated using cryptographic signatures. The Amazon API documentation explains how to authenticate requests. The API team also provides sample code in C#, Java and Perl. Two C# samples are provided, one for applications using the SOAP interface, and another for applications using REST.

My application uses SOAP, and so I started with that sample. The SOAP sample, it turned out, uses the Microsoft.Web.Services3 namespace, which belongs to the Web Services Enhancements (WSE) class library. WSE appears to be a .NET 2.0, Visual Studio 2005 thing, and is superceded by WCF. If I have to touch my application, I would much rather update it to use WCF, .NET 3.5, and Visual Studio 2008 than to WSE.

Thankfully, a number of folks tackled the problem already. The WCF solution implements the IClientMessageInspector interface to gain an opportunity to sign SOAP requests just before they are sent. The signing logic isn’t particularly complex. It must, however, implement the letter of the specification,or requests are dropped. The remainder of this post outlines a short sample program illustrating how to generate authenticated WCF requests to the Amazon product advertising API. You can download the complete sample from the link at the top of this post.

Step 1 – Create a sample console application

  1. In Visual Studio 2008, select New/Project… from the File menu.
  2. Select Console Application from Visual C#/Windows, and enter the application’s name.
  3. Click OK

Visual Studio creates a new console application. So far, this isn’t different than any other console app.

Step 2 – Add a web service reference

  1. In the Solution Explorer view, right click References, then select Add Service Reference…
  2. The Add Service Reference dialog appears. Type in the Amazon Product Advertising API WSDL URL in the Address box: http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl.
  3. Click Go. Visual Studio takes a moment to download the service description, and then populates the Services box. You should see AWSECommerceService in there.
  4. Type in the namespace for the code that Visual Studio will generate. I used Amazon.ECS. Click OK.

Visual Studio now creates a service reference and adds it to your project. You can see it under the Service References folder in Solution Explorer. Your application will now also have an app.config file added, listing WCF binding and endpoint information for the added service.

Step 3 – Add code to access the Product Advertising API.

You could update your program as follows to have it connect to the product advertising API and search for books with “WCF” in their title. Make sure to add a using statement to reference the namespace you chose for the service in step 2.

    using System.ServiceModel;
    using AmazonProductAdvtApiWcfSample.Amazon.ECS;

    class Program {
        // your Amazon ID's
        private const string accessKeyId    = "YOURACCESSKEYIDHEREX";
        private const string secretKey      = "YOURAMAZONSECRETKEYHERE/YESITSTHISLONGXX";

        // the program starts here
        static void Main(string[] args) {

            // create a WCF Amazon ECS client
            AWSECommerceServicePortTypeClient client = new AWSECommerceServicePortTypeClient(
                new BasicHttpBinding(),
                new EndpointAddress("http://webservices.amazon.com/onca/soap?Service=AWSECommerceService"));

            // prepare an ItemSearch request
            ItemSearchRequest request   = new ItemSearchRequest();
            request.SearchIndex         = "Books";
            request.Title               = "WCF";
            request.ResponseGroup       = new string[] { "Small" };

            ItemSearch itemSearch       = new ItemSearch();
            itemSearch.Request          = new ItemSearchRequest[] { request };
            itemSearch.AWSAccessKeyId   = accessKeyId;

            // issue the ItemSearch request
            ItemSearchResponse response = client.ItemSearch(itemSearch);

            // write out the results
            foreach (var item in response.Items[0].Item) {
                Console.WriteLine(item.ItemAttributes.Title);
            }
        }
    }

If you enter your Amazon access key ID into accessKeyId and run this program before the August 15 deadline, you might just obtain results. Your console should list the top 10 results for the “WCF” query against Amazon’s US book catalog. If you read this after the deadline has expired, you must complete the remaining steps before you can see the results.

Step 4 — Add the authentication code

That’s why we’re here. This sample adds the authentication SOAP headers using three classes:

  • AmazonSigningMessageInspector implements the IClientMessageInspector interface. The implementation of the BeforeSendRequest method in this class generates the request signature and adds the appropriate headers to the request.
  • AmazonSigningEndpointBehavior implements the IEndpointBehavior. The implementation of the ApplyClientBehavior in this class adds our message inspector to the ECS client at the right moment.
  • AmazonHeader is a small helper class implementing MessageHeader. Our message inspector uses instances of this class to add the authentication headers into the SOAP request.

Rather than include the full listing of these classes, let’s focus on the portion that actually signs the request.

public object BeforeSendRequest(ref Message request, IClientChannel channel) {
    // prepare the data to sign
    DateTime    now             = DateTime.UtcNow;
    string      timestamp       = now.ToString("yyyy-MM-ddTHH:mm:ssZ");
    string      signMe          = operation + timestamp;
    byte[]      bytesToSign     = Encoding.UTF8.GetBytes(signMe);

    // sign the data
    byte[]      secretKeyBytes  = Encoding.UTF8.GetBytes(secretKey);
    HMAC        hmacSha256      = new HMACSHA256(secretKeyBytes);
    byte[]      hashBytes       = hmacSha256.ComputeHash(bytesToSign);
    string      signature       = Convert.ToBase64String(hashBytes);

    // add the signature information to the request headers
    request.Headers.Add(new AmazonHeader("AWSAccessKeyId", accessKeyId));
    request.Headers.Add(new AmazonHeader("Timestamp", timestamp));
    request.Headers.Add(new AmazonHeader("Signature", signature));

    return null;
}

BeforeSendRequest gets called just before the SOAP request is put out on the network. Our implementation of this method comutes a hash-based message authentication code (HMAC) of the operation and current time using the SHA256 hash function. It also puts the access key ID, timestamp and signature in the SOAP request headers. This embeds tags like the following in the SOAP request:

<soap:Header
   xmlns:aws="http://security.amazonaws.com/doc/2007-01-01/">
   <aws:AWSAccessKeyId>YOURACCESSKEYIDHEREX</aws:AWSAccessKeyId>
   <aws:Timestamp>2009-08-15T23:59:59Z</aws:Timestamp>
   <aws:Signature>SZf1CHmQnrZbsrC13hCZS061ywsEXAMPLE</aws:Signature>
</soap:Header>

Step 5 – Make the Amazon ECS client authenticate

Finally, to make our Amazon ECS client actually authenticate its requests, modify the main() method as follows:

// create a WCF Amazon ECS client
AWSECommerceServicePortTypeClient client = new AWSECommerceServicePortTypeClient(
    new BasicHttpBinding(BasicHttpSecurityMode.Transport),
    new EndpointAddress("https://webservices.amazon.com/onca/soap?Service=AWSECommerceService"));

// add authentication to the ECS client
client.ChannelFactory.Endpoint.Behaviors.Add(new AmazonSigningEndpointBehavior("ItemSearch", accessKeyId, secretKey));

There are three changes from our original console program:

  1. The binding constructor now takes a BasicHttpSecurityMode.Transport argument. This forces an HTTPS connection. The Amazon web service refuses to accept authenticated requests over plain HTTP.
  2. The endpoint address starts with “https:” instead of “http:”. The remainder of the URL did not change.
  3. An instance of our endpoint behavior class is added to the client’s channel factory. This ensures that our message inspector will get plugged in when the client creates new connections, and will get to sign outgoing SOAP messages.

That’s it.

This is all that’s required to get your WCF based Amazon Product Advertising API application to send authenticated requests. If you build and run the application now, your console should list 10 book titles returned from the service.

Worked for you? Didn’t work? Let us know in the comments!

Read part 2.

115 Responses to Signing Amazon Product Advertising API requests — the missing C# WCF sample

  1. Andrew says:

    If you need to increase the maxReceivedMessageSize because the search result is too large, then do this:

    // modify the MaxReceivedMessageSize to prevent response errors for large responses
    BasicHttpBinding basicBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
    basicBinding.MaxReceivedMessageSize = 2147483647;

    // create a WCF Amazon ECS client
    AWSECommerceServicePortTypeClient client = new AWSECommerceServicePortTypeClient(
    basicBinding,
    new EndpointAddress(“https://webservices.amazon.com/onca/soap?Service=AWSECommerceService”));

  2. Matt says:

    Oren,

    Can I just say thank you for taking the time to post this solution, I have integrated it in no time and has saved me lots of hassle.

    Thank you,
    Matt

  3. Jason Foglia says:

    I am getting an The “HTTP request was forbidden with client authentication scheme ‘Anonymous'” Exception how could I fix this.

  4. Jason says:

    Also, is there a way the WCF reference can use async methods.

  5. Oren Trutner says:

    Jason, as for the error message, make sure to enter *your* Amazon access key ID and secret key into the accessKeyId and secretKey constants at the top of the sample. The string values I put in the sample are not real Amazon keys.

    Also, make sure you are using SSL — see step 5 in the article.

    To generate async methods, in step 2, before you click OK, click Advanced…, then check the “Generate asynchronous operations” box. The client object will now have async method, e.g. BeginItemSearch(…)

  6. Jason says:

    Oren, Thanks for reply.

    I realized I forgot to check the box to Generate Async Methods.
    I used my own accesses key and secret key.

    The problem I am coming up with is this:
    The HTTP request was forbidden with client authentication scheme ‘Anonymous’.

    I am not the sharpest knife in the shed when it comes to C# but it looks like I am having an issue with security and windows. I really am not sure how to set this up the code for security. I did try and add the X509Certificate to AWSECommerceServicePortTypeClient but with no effect.
    The code looks like this:
    client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(@”C:\cert-YOUR AMZ CERT.pem”);

    • Oren Trutner says:

      Hey Jason, I cannot replicate the problem you describe. The closest I could get was (1) when using invalid access/secret keys, and (2) when not using SSL. You shouldn’t need to add a client certificate on top of everything else. The only additional thing I can think of is if you have a web proxy between you and the Internet that might require authentication.

      If anyone else is seeing an issue similar to Jason’s please post and we can try and correlate the circumstances.

  7. Jason says:

    Hey Everyone and Oren,

    I figured out my problem. It was with signing async messages, instead I just downloaded the x509 cert from amazon and applied it to the AWSECommerceServicePortTypeClient Object like this
    client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(@”C:\LOCATION OF YOUR CERT\cert-XXXXXXXXXXXX.pem”);

  8. Erica says:

    I am having the same issue as Jason, unfortunately. Your sample and write-up here is awesome, and I am happy to not integrate an antiquated MS technology and instead use WCF. I wish I could figure out what the remaining problem is.

    We use a command line build, so I generated the .cs file from the .wsdl by adding the service as described, and used that. This is probably neither here nor there, but I thought I would bring it up since Jason mentioned these async messages….

    Anyway, I feel pretty confident that my certs are right. Any advice? A lot of our sites functionality integrates with this, so I am getting nervous.

  9. Jason says:

    Hey Erica,

    I was able to accomplish my task by simple adding the x509 cert. from amazon to the WCF connection.

    BasicHttpBinding basicBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
    client = new AWSECommerceServicePortTypeClient(basicBinding, new EndpointAddress(“https://webservices.amazon.com/onca/soap?Service=AWSECommerceService”));
    client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(@”C:\LOCATION OF YOUR CERT\cert-XXXXXXXXXXXX.pem”);

    You can run test request as well. If you comment out the cert. then you will see problem trying to connect to amazon. Removing the comment you get no problems trying to connect. Good Luck!

  10. Wilson says:

    Hi Oren,

    First of all, thanks for the clear and well commented code.

    What if I cannot (or don’t like) to use a certificate. I have the same problem “HTTP request was forbidden with client authentication scheme Anonymous” and I can’t use a certificate. Any comment?

  11. Oren Trutner says:

    Hey Wilson,

    I don’t believe certificates have anything to do with it. You shouldn’t need a certificate at all to get your requests to authenticate.

    The error message you mention is the one that the Amazon web service sends back if it doesn’t think your request is authenticated. Common reasons for that, if you’re using the sample from this post, are:

    – make sure to put your amazon access ID and secret key in the appropriate constants at the top of the program.
    – make sure to implement all 3 parts of step 5 above; you must have an SSL connection, and the signing behavior must be registered with the client
    – no longer an issue: it used to be too easy to pass an incorrect operation name in the AmazonSigningEndpointBehavior constructor. I updated the sample to extract the operation name from the message itself instead.

    A good test would be to download the sample app (http://flyingpies.s3.amazonaws.com/AmazonProductAdvtApiWcfSample.zip), update Program.cs in the Simple project to use your access key ID and secret key, and check if that runs correctly.

    You might also want to look at part 2 of this post, which addresses some of the common issues folks experienced (https://flyingpies.wordpress.com/2009/08/13/signing-amazon-product-advertising-api-cwcf-part-2/).

    If you would like to share a sample piece of code that fails for you, I’d love to look at that too.

  12. Wilson says:

    Oren,

    Oh! forgot it! It’s Ok! It was just one of those little mistakes.

    Thanks again.

    By the way, I loved the way the coding was done! Extremely clean code! Great work! 😉

  13. Sergei says:

    Just have to say Thank you! for the awesome code example. Simple to read, simple to use, simple to understand. Thanks a lot

  14. Agustin says:

    Hey Oren! Amazon should hire you! great code.. clear and simple. Implemented it in less than 20 minutes.

  15. Pingback: Voxound - the music collection manager and player that helps you tag your mp3 songs

  16. Jeffery says:

    Thanks a bunch Oren. I was able to get it to work with your sample code. But now when doing an Item Search that has a lot of items in it I get the following error:

    System.ServiceModel.CommunicationException:Error in deserializing body of reply message for operation’ItemSearch’. —> System.InvalidOperationException: There is anerror in XML document (4, 9806). —> System.Xml.XmlException: Themaximum string content length quota (8192) has been exceeded whilereading XML data. This quota may be increased by changing theMaxStringContentLength property on the XmlDictionaryReaderQuotas objectused when creating the XML reader. Line 4, position 9806.

    That’s only part of the error as it is very long.

    Any Ideas?

    Every thing works ok if the Item I search for only has 10 or so items but when I searched in DVD for Star Trek which there are hundreds or thousands of items I get the error above. I do have the int.MaxValue on that binding line in your sample code.

    Thanks,

    JefferyS

    • Oren Trutner says:

      Hey Jeffery,

      The binding object has a number of limits you could increase. I believe binding.MaxReceivedMessageSize = int.MaxValue is the relevant one, but you might also want to look at binding.MaxBufferSize and binding.MaxBufferPoolSize.

      My own app (not the sample) pulls 10 items at a time, with a pretty large response group, and pages through hundreds of responses. It appears to work fine with the increased limits. I know you can pull 10 items at a time, or 20 with a batched request. For more, I believe you need to page through multiple request responses. If you’re still stuck, could you share a code sample that fails? I’ll try out the DVD/startrek search later today if I can.

      I hope this helps!

      • Jeffery says:

        I finally found how to fix the problem.

        binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;

        Found this setting in the web.config but it didn’t fix it so I looked to set it in code.

        Thanks a lot for your help!

        JefferyS

      • Yousef says:

        Thanks Jeffrey,

        This code line solved my problem. My client was inputing search keywords that were pulling in a lot of data back and I was getting the quota exceeded error, until I found your code below:

        binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;

        Thanks!

        Jeffery :
        I finally found how to fix the problem.
        binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
        Found this setting in the web.config but it didn’t fix it so I looked to set it in code.
        Thanks a lot for your help!
        JefferyS

  17. Jake says:

    Big Thanks to both Oren for the work and Jeffery for solving my buffer size error!

  18. Carlos says:

    I’m trying to get the ISBN and it just gives me a blank response. I’m able to get the title. Has the ISBN feature been disabled?

  19. Anonymous says:

    I’m getting:

    The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

    —–
    I’ve changed the size in the .config file and added the following code: (It’s still not working)

    BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
    binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
    binding.MaxReceivedMessageSize = int.MaxValue;
    //Changed in the .config file and it still doesn’t work

    —–

    Thanks Oren for the previous response

  20. Carlos says:

    Got it fixed. The first posting was the fix 🙂 Sorry

    // modify the MaxReceivedMessageSize to prevent response errors for large responses
    BasicHttpBinding basicBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
    basicBinding.MaxReceivedMessageSize = int.MaxValue;

    // create a WCF Amazon ECS client
    AWSECommerceServicePortTypeClient client = new AWSECommerceServicePortTypeClient(
    basicBinding,
    new EndpointAddress(“https://webservices.amazon.com/onca/soap?Service=AWSECommerceService”));

    THANKS TO ALL

  21. Carl says:

    Many many thanks – this helped tremendously!

  22. Marco Russo says:

    I’m getting a 400 Bad Request exception using your sample – I correctly replaced accessKeyId and secretKey. Is there anything else I can check? Is the service running?

    • Oren Trutner says:

      Marco, I checked the service, and it appears to be running okay as of 5 minutes ago. Did you change anything else in the sample? Can you share the complete exception? Thanks!

  23. Carlos says:

    At this time everything seems to be working except in some searches.

    When I try and use item.SmallImage.URL it works for some searches but not for items items like request.Title = “science”;

    I get the following error:

    Object reference not set to an instance of an object.

    What can be the problem?

    • Carlos says:

      It seems to be my visual studio. Sometimes it wants to get the url and others it doesn’t. I close VS2008 and reopened it and ran the code. It worked. umm…. can it be the service or my VS2008?

      Thanks for all the great documentation.

  24. Carlos says:

    Is there any way to get the app to return more than 10 results?

    • Oren Trutner says:

      For up to 20 items, you could batch two requests together — see part 2 of the post. Beyond 20 items, you will need to issue multiple requests, each time specifying the next 10-item page to retrieve using request.ItemPage. If I recall correctly, the Amazon TOS requires that you don’t issue more than one request per second from each IP address your application runs on.

      • Carlos says:

        This might be the limitations that Amazon has added.

        I’m getting this error when adding a third request:
        “Index was outside the bounds of the array.”
        in the line for the second foreach loop:
        foreach (var item in response.Items[0].Item)

        Thanks for the help but I think Amazon thought of this before releasing their SOAP service.

  25. Carlos says:

    This might be the limitations that Amazon has added.

    I’m getting this error when adding a third request:
    “Index was outside the bounds of the array.”
    in the line for the second foreach loop:
    foreach (var item in response.Items[2].Item)

    • Oren Trutner says:

      Originally, the product advertising API would let you obtain up to 10 items per request, and no more. If you wanted more than 10, you would have to send more requests to get more groups of 10. In each request, you would specify the “page” of items you wanted. Page 1 for the first 10, Page 2 for the second group of 10, and so on. You could go up to Page 400, for a total of 4000 items. If there were more than 4000 items in the result set, you were out of luck (and still are). Amazon also asked (in their TOS) that you do not send more than one request per second. To obtain those 4000 items, you would have to send 400 requests, taking at least 400 seconds to complete. None of the samples I posted demonstrate this technique. It’s pretty straightforward, however — just repeat the steps of setting up an ItemSearchRequest, an ItemSearch object, and then calling client.ItemSearch. Each time set request.ItemPage to the next page number. To get the result, always use only response.Items[0].

      Later on, Amazon added the option to “batch” up to two requests — but not more — in one message sent to their service. You could batch two ItemSearch requests in one message. You would access the results in response.Items[0] and response.Items[1]. You can now get 20 items in one message you send, in two groups of 10. This is what the “batch” sample does. But Amazon won’t let you go higher than two in one. If you need more, you have to go back to the original method of sending numerous requests, each one for a different “page”. The good news is that you can get 4000 items in 200 seconds instead of 400.

  26. Anlov says:

    Hi. I have error message:

    “Your request should have atleast 1 of the following parameters: Signature, Timestamp.”

  27. Brian says:

    The issue of getting max length errors can be fixed in code, or if you want to use the config file like you normally would I’ve updated my answer on SO with code that allows full use of the config file which you can see here.

  28. Jake says:

    Thanks for the tip!!

  29. Chris says:

    I got the sample working but when I try to get the feature id of a DVD,

    item.ItemAttributes.Feature[0]

    The text always gets cut off. I tried using a different WSDL
    http://webservices.amazon.com/AWSECommerceService/2008-10-06/AWSECommerceService.wsdl
    but when I do that, I get the error like they did above

    The HTTP request was forbidden with client authentication scheme ‘Anonymous’.

    • Oren Trutner says:

      Hey Chris, I can see this happening too, e.g. with SearchIndex=”DVD”, Title=”Matrix”, and ResponseGroup=”Large”. I believe, however, this is the way the Amazon service returns the content, rather than an artifact of WCF. If you look at the returned XML directly (put a breakpoint in AmazonSigningMessageInspector.AfterReceiveReply and look in reply.ToString()), you can observe that the text in Feature elements is clipped.

  30. Ryan Morlok says:

    Thanks for the great posts, Oren. Really appreciate you summing up the problem(s) and solutions so nicely and providing sample code.

  31. Adam Kahtava says:

    Thanks Oren. I wish I would have found this earlier, I implemented the WSE 3.0 implementation then realized it didn’t work on shared hosting (GoDaddy), then came across this article. I wish I came here first. 🙂

    -Adam

  32. interadmedia says:

    Thanks for the tip. The code is truly useful and can be applied easily

  33. Kirti says:

    Oren,
    we have already using WSDL as WEB reference not Service reference, so AWSECommerceServicePortTypeClient cannot be accessed, what should I do? I cannot replace Web reference to Service reference.

  34. Kirti says:

    Oren,
    I used ServiceReference and it worked, thanks.
    you can see that some of the items from Electronics department are not displyed, other departments are working fine, SearchIndex like DVD or Software are not working, Please help me, what should I do??

  35. Signing Amazon Product Advertising API requests — the missing C# .NET SOAP sample???

    Like many others, on August 15th my simple Amazon book search started to fail with the “The request must contain the parameter Signature” exception.

    This WCF sample works well however my site is site running .NET 2.0 Framework (i.e WCF is not supported).

    Could anyone help me with example of SOAP request signing using the .NET 2.0 Framework? Or in other words, a sample that uses a Web Reference to http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl

    Thanks!

    Chris

  36. kirti says:

    Oren, In my web site, BrowseNode=172659 works fine but BrowseNode=491286 is not pulling anything, and website pulls computer category items but its subCategory items like Desktop is not showing any items http://www.byjoel.com/ProductList.aspx?DepartmentID=1&CategoryID=10&SearchIndex=PCHardware&PercentOff=0&Level=1&BrowseNode=565098&BNLast2=541966&BNLast3=&BNLast4=&BNLast5=&BrowseNodeName=Desktops&BNLast2Name=&BNLast3Name=&BNLast4Name=&BNLast5Name=, do i have to use Global Application class so that signing is done automatically at app startup?? please help me.

  37. Kirti, Oren, and Others,

    I thought I had it, but one more detail. How do you deploy the WSE 3.0 Microsoft.Web.Services3.dll that is referenced in http://developer.amazonwebservices.com/connect/entry.jspa?externalID=2481&categoryID=14,

    I installed the WSE, and I added Microsoft.Web.Services3.dll to my project references, and I marked the library as ‘Copy Local’.

    This Amazon WS .NET 2.0 solution runs fine locally via VS 2008,, but when deployed I recieve this error: Could not load file or assembly ‘Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’

    Is there a web.config entry that I need?

    Chris Mangiapane

    • kirti says:

      Chris,
      you have add reference, goto your project, Add Reference > in .NET tab > Search for Microsoft.Web.Services3 then click Ok. thats it there is no need to add any entry in web.config

  38. Pingback: Accessing Amazon Web Services with C#.Net | dennis' blog

  39. Hi Oren,

    nice job, I was able to implement this in no time! Thanks a lot! I even blogged about this: http://dennispiccioni.com/wordpress/archives/309

  40. Dennis Piccioni says:

    Doh! My Google toolbar’s autofill function filled in my email instead of my web site into the website field on the comment form and I only realized this as I clicked Submit Comment.

  41. Marco Russo says:

    I had a Bad Request error (400) caused by incorrect timestamp formatting.
    I solved it by replacing the line

    string timestamp = now.ToString(“yyyy-MM-ddTHH:mm:ssZ”);

    with

    string timestamp = now.ToString(“yyyy’-‘MM’-‘dd’T’HH’:’mm’:’ss.fffffffK”);

    Problem caused by different locale settings, I suppose.

    Marco Russo

  42. Klaus Rafn Hansen says:

    Thank you very much, I simply couldn’t get through to the web service due to the change in the security settings. This helped me through it and now I have a working application again 🙂

    Klaus

  43. Chris Paul says:

    Total newbie here. I have a website that is running .net framework 3.5. How do I add the Amazon wsdl to my website? Do I need to install WSE from Microsoft, also? Thank you!

    • Chris says:

      OK, so I figured out how to add a web reference in VS Web Developer. I try to reference AWSECommerceServicePortTypeClient but it cannot be found. I am able to see AWSECommerceService in intellisense, though.

  44. Robert Wager says:

    I am getting: The remote server returned an error: (407) Proxy Authentication Required. There is a proxy between me and the Internet. I am not sure what to do. Any help would be appreciated.

  45. Hi,

    I made a sample project, based off this code. Please check it out:

    http://amazonassociates.codeplex.com/

  46. Ehsan says:

    Hey,
    I hope there is something happening bad in amazon web service. The above code is returning the following error:

    The remote server returned an unexpected response: (400) Bad Request.

    Can anybody tell me whats the problem actually?

    Thanks,

  47. Ehsan says:

    Hello Everybody,
    I think that’s happened because of amazon webservice maintainance. Now again its working. Sorry to bother you.

  48. andrey says:

    Hello, great sample, thank you!
    In my application in C# I need to generate signature (so called ‘version 2’) for my below REST SellerListingSearch request:

    http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=&Operation=SellerListingSearch&SellerId=A1IOIYBJ9FI2UE&OfferStatus=Open&ListingPage=1&Signature==&Timestamp=2010-02-16T00:10:25Z

    Will the sample code for getting signature [from BeforeSendRequest method] work for such REST request?

    If not – could you please advice where I can find such code?
    Thanks!
    Andrey

  49. Scott says:

    Just wanted to say that it took me forever to find this. Thank you for taking the time to do this, you saved me so much grief!

    On a side note, why does Amazon documentation suck so bad? And, why do they have to change the name of their service so much?? /rant

    Thanks again.

  50. Paddy Clarke says:

    Sorry for the noobie question but where exactly are we calling the “BeforeSendRequest” method ? The problem is that I am unable to compile because I am getting an error

    The type or namespace name ‘Message’ could not be found (are you missing a using directive or an assembly reference?)

    for the first parameter of this function. I couldn’t find anywhere that the Message parameter is constructed.

  51. roundsee says:

    Hi,
    I have tried the sample code and its working fine.
    But if I try to search by Keywords, the result is always empty.

    Here is my code in VB
    This will always return empty result,
    Dim reqLookup As New SellerListingSearchRequest
    reqLookup.SellerId = SellerID
    reqLookup.ListingPage = 1
    reqLookup.Keywords = “Printer”

    Is there any other parameter that need to be passed ?
    Thanks

  52. Kunal says:

    Thanks ,
    its working fine.
    Great help.

    i just want to know , How many types of SearchIndex is provided by Amazon (i.e. Books in your code )
    if possible send me email

    Thanks again.

  53. Wilson says:

    Hi Everyone,

    First, Thanks for the solution.

    Reached the max Int32.MaxLimit. Is there a way I can clear the buffer?

    Thanks

  54. Diego says:

    I was reviving and old program I had when I encounter “bad request” errors….
    10x for the usefull information!
    Diego
    Dieg’s World

  55. Ady Levy says:

    Thanks ! you saved me heaps of time !

    let me know if you want me to buy you a beer sometime 🙂

  56. pavan says:

    HI,

    Thax a lot to every one for such a nice solution,I am downloading products data from amazon using AWS.

    after a couple of downloads say “6000 data”,I get this 400 error message any one have come accross the same.

    Please help !

  57. Numan says:

    I am searching books through ISBN it is returning fine now I am trying to get the category of a book but i can’nt find it How to get the category of a book.?
    i have looked into this item.ItemAttributes.Category but it returns null.
    can any one help me ?

  58. Numan says:

    IS there any way to get more than 4000 records.?

  59. Wonderful I highly recommend this site!

  60. Seb says:

    Thanks for this great site, i’ve been looking for ages for some decent sample code!

  61. Zup says:

    The newest Version of the Amazon Webservice (April 2011) did not work for me with this sample. The ItemSearchResponse is always NULL for the German locale (https://webservices.amazon.de/onca/soap?Service=AWSECommerceService). If i trace the result within the AfterReceiveReply Method the XML Reply seems to be correct but ItemSearchResponse is always NULL. The older Version from this sample works correct.

    I have cheated now the reference.cs from this sample in my Project and it seems to work. But it cannot be the proper solution.

    You can reproduce it by refreshing the Service Reference and run the sample for the German locale.

  62. Anonymous says:

    Hello,

    I tired to do the same thing but with asp.net application (web form) I have an error :

    Unable to generate a temporary class (result=1).
    error CS0030: Cannot convert type ‘Amazon.ImageSet[]’ to ‘Amazon.ImageSet’
    error CS0029: Cannot implicitly convert type ‘Amazon.ImageSet’ to ‘Amazon.ImageSet[]’

    and and I don’t understand why ?? I added all references and the last wsdl file !!!

    Please could help me 😦

    • Gerald says:

      In case anyone else has this problem, I resolved it with a partial class to define the implicit conversions. This may have side effects (I’m still testing scenarios), but resolves the above error.

      namespace AmazonProductAdvtApiWcfSample.Amazon.ECS
      {
      public partial class ImageSet
      {
      public static implicit operator ImageSet[](ImageSet i)
      {
      return new ImageSet[] { i };
      }

      public static implicit operator ImageSet(ImageSet[] i)
      {
      if (i != null && i.Length >= 1)
      {
      return i[0];
      }
      return new ImageSet();
      }
      }
      }

  63. Lloydz1 says:

    Hi guys does anyone knoe what i need to ammend to make this lookup on amazon.co.uk?

  64. Anonymous says:

    Hi oren

    thank you so much for ur amazon code, as i am fresher for .Net developing this code helped me a lot for our project,

    -prapoorna

  65. Gordon says:

    Wow, Oren, this is fantastic. The Amazon API is woefully underdocumented for .NET SOAP. They have changed their API slightly since then (requiring the AffilateID, for example). I want to do a CodeProject article, but my code uses your helper classes, so I want to check with you first.

    Also, I hope you post again soon.

    Thank you.

    Gordon

    • Oren Trutner says:

      Hey Gordon, I haven’t updated this posting for a while. The community can use fresh documentation, and I hope your codeproject article can fill that gap. I’ll even link to it from here, if you let me know once it’s online. Please feel free to use any of the code in here — it is shared with the intent of being useful. Think of it as MIT licensed (http://www.opensource.org/licenses/mit-license.php) — you can pretty much do whatever you want with it; if for some odd reason it erases your hard drive, you can’t say it’s my fault though.

      -Oren

  66. Eric Irwin says:

    Hi,
    I am using the same code as aboce, and when I hit the AfterReceiveReply() My message XML is fine, but for some reason, It is still returning null from my ItemSearch call. Do you know why this might be happening

    • Raj Vijay says:

      Hello ! Did you get a chance to make it work ? I added the AssociatedTag but still the client.ItemSearch(itemSearch); is returning null.Any ideas ?

  67. Quintin says:

    Good day,

    Thank you for this – I have used it before and it worked wonderfully. But now…

    I really think this needs an update – the ItemSearchCompleted delegate is returning with a null e parameter.

  68. jaykannan@jayjay.com says:

    Looks like it requires an AssociateTag. can you update the sample?

  69. suchin says:

    Thank You very Much , I find code .net get api amazon .

  70. Anonymous says:

    You’re rock !!! thanks

  71. yankel says:

    Hi Oren
    Thanks very much for your devoted and useful help.
    I’ve tried to use your code but visual studio always returns the “Object reference not set to an instance of an object.” error at “foreach (var item in response.Items[0].Item)” statement.
    Please help me asap.
    Thank you

    • yankel says:

      i also added System.Diagnostics.Trace.WriteLine(reply.ToString() as you suggested above and the output pane shows perfectly populated xml results, however the last statement always indicates about the “Object reference not set to an instance of an object.” error and i it still stops debugging.

  72. Amandeep says:

    Can anybody link me 2 php code for this or i have to do using c# only ?
    Can anybody provide with this plugin for replying in word-press as well i will be really thankful to you guys.

    Thanks
    Amandeep

  73. Santosh Tripathi says:

    there is error

    Unable to generate a temporary class (result=1).
    error CS0030: Cannot convert type ‘AmazonAWS.ServiceReference1.ImageSet[]’ to ‘AmazonAWS.ServiceReference1.ImageSet’
    error CS0029: Cannot implicitly convert type ‘AmazonAWS.ServiceReference1.ImageSet’ to ‘AmazonAWS.ServiceReference1.ImageSet[]’

    any help….

  74. Paul B says:

    Just in case anybody is wondering how to get this example to work as at 19/07/2014 there are a couple of things you need to be aware off.

    First thing is that you need to add an associateID to your item search e.g.

    itemSearch.AWSAccessKeyId = accessKeyId;
    itemSearch.AssociateTag = “exampleassocid-20”;

    This gets the request accepted. The next issue is you get a null object error. The way to fix this is to right click on Amazon.ECS within Service References and click “Update Service Reference”. Finally you’ll then get the ImageSet error as above and that can be fixed by following a comment by J Bradshaw on this page:- https://forums.aws.amazon.com/thread.jspa?threadID=72429

    From then on it’s all plain sailing, thanks for the example it really is a great help in autheticating with Amazon.

  75. Lerner says:

    Hi
    I try’d to run the sample but i’m getting a System.NullReferenceException because the response is null.
    Do you know why? I added my keys.
    Thanks

  76. Anonymous says:

    Same here – array comes back null no matter what is searched on.

  77. Pingback: Getting Connected to Amazon Advertising API with VB.NET | Srife Blog

  78. Bob says:

    +1 response is null

  79. Pingback: Getting Connected to Amazon Product Advertising API with VB.NET | Srife

  80. Danny Visel says:

    You’ve probably the greatest sites.|

  81. https://flyingpies.wordpress.com does it yet again! Quite a thoughtful site and a thought-provoking article. Thanks!

  82. Pingback: Amazon API 400 Bad Request - How to Code .NET

  83. Great info. Lucky me I recently found your blog by accident (stumbleupon).
    I’ve book marked it for later!

Leave a reply to Amandeep Cancel reply