Beginners Guide to getting started with Amazon Product Advertising API


This is a beginners guide to consuming the Product Advertising API of Amazon. I will be targeting “ItemLookup” method here. But any other API methods like “ItemSearch”, “BrowseNodeLookup”, “SimilarityLookup”, “CartAdd”, “CartClear”, “CartGet”, “CartModify” should look like a cake walk after this.

Pre-requisites:

  • An Amazon AWS (Amazon Web Services) account
    If you do not have one, just go to aws.amazon.com, sign up, provide your credit card info (dont worry you wont be charged until you cross the free quota limit)
  • Your AWS Account ID, Access Key ID and Access Secret Key from the “Security Credentials” page
    Image
    Click on the “Show” to get your Secret Access KeyImage
    The AWS Account ID is the Account ID or the so called Associate Tag
  • Identify the Amazon Region which you are going to query. This is basically the region in which you are searching for an amazon product. ex. if you want to search this product in Amazon Italy site, then your region is “webservices.amazon.it“. Below are the list of locales available for you:
    Amazon API - Locales

That’s all. Now you are all set to consume the Amazon Product Advertising API.

Consuming the API is not that straight forward, especially due to the authentication process involved. Which is good in one way. And this is where most us normally tend to get frustrated. I totally agree. I hope this post help you avoid wasting days of investigations on that. I also hope Amazon improves their documentation as well.

Forget all those things for the time being….At the end of the day, all we need get is a simple URL, which you can paste it in your browser and see the results. Let me show you what i meant by this. Then we will proceed on how to construct this URL.

Final Request URL:

http://webservices.amazon.de/onca/xml?AWSAccessKeyId={AccessKeyID}&AssociateTag={AssociateTag}&Availability=Available&IdType=EAN&ItemId=4210201052623
&MerchantId=Amazon&Operation=ItemLookup &ResponseGroup=ItemAttributes%2COffers
&SearchIndex=All&Service=AWSECommerceService&Timestamp=2013-11-20T15:03:00Z
&Version=2009-03-31&Signature=k1DNFOxZeIa0KNVTHLZVPUhVd2%2B6i9rLAPH75h7TCiw%3D

I have removed the Associate Tag and Access Key Id, from the URL, for security purpose.

Final Response on the Browser:

Amazon API - Response

It’s that simple!!

Steps involved in constructing this URL – also called the “Signing the URL”

A small note: I wont be able to explain the signing process involved in detailed here. That would be too lengthy and will get you bored. But if you start getting errors on signing process, you will need to go through them & understand them. Check amazon API documentation for that…sorry…:(

Use Case: Get the details of a product with ASIN ID “B004CRSLUI”, in Amazon France Site.

STEP 1: Construct the Unsigned URL

This is straightforward. Fill the below template with your values from the “Pre-requisites” section:
http://webservices.amazon.fr/onca/xml?Service=AWSECommerceService&Operation=ItemLookup&SubscriptionId={Access Key ID}
&AssociateTag={Associate Tag}
&Version=2011-08-01&ItemId=B004CRSLUI
&IdType=ASIN
&Condition=All&ResponseGroup=ItemAttributes,OfferFull,Offers

STEP 2: Generate the “Signature” parameter (which you see towards the end of the above url), using your Access Key, Access Security Key and the unsigned URL

This is the tricky part. The signature is generated by using an encoding algorithm. It is a generic algorithm (HMACSHA256) that we have in most of the coding languages C#, Java or PHP. You can get the library for your favorite language from here: http://aws.amazon.com/code/Product-Advertising-API

A sample “Signature” value looks something like this:
zo4wTc7ZIujHz1zAL4sR1%2FHCEiUWg%2Fde2f%2FRO0f31LI%3D

For C# users, there is a helper class called “SignedRequestHelper.cs” available from one of the sample codes in the above link. You can also download that file here SignedRequestHelper.cs.

Once added to your C# project, you need to refer the namespace:

using AmazonProductAdvtApi;

Create a generic method which invokes the SignedRequestHelper class:

public static string GenerateSignedRequestUrl(string skuId)

{
//Initialise the Amazon Signing helper method with the access key and access secret
SignedRequestHelper helper = new SignedRequestHelper(“{AwsAccessKeyId}”, “{AwsSecretKey}”, “webservices.amazon.fr”);

//Setup the request dictionary with the required parameters
IDictionary<string, string> r1 = new Dictionary<string, String>();
r1[“Service”] = “AWSECommerceService”;
r1[“Version”] = “2009-03-31”;

r1[“Operation”] = “ItemLookup”;
r1[“ItemId”] = skuId;//”B004CRSLUI”; //You can even pass comma separated values here
r1[“IdType”] = “ASIN”;

r1[“Availability”] = “Available”;
r1[“SearchIndex”] = “All”;
r1[“AssociateTag”] = “{AwsAssociateTagId}”;
r1[“ResponseGroup”] = “ItemAttributes, Offers”;
r1[“MerchantId”] = “Amazon”;

//Sign the requestUrl using the Helper class
return helper.Sign(r1);
}

STEP 3: In you C# code, make an HttpWebRequest for the above “Signed” Url:

public static XDocument InvokeService(string requestUrl)
{
XDocument responseDocument = null;
try
{
//Convert the Url from string format to Uri format
Uri requestUri = new Uri(requestUrl, UriKind.Absolute);

//Invoke the Web Service Url
WebRequest request = HttpWebRequest.Create(requestUri);

#region Proxy

//Invoke the proxy objects UNCOMMENT ONLY IF YOU GET Remote Server Access Denied Error
//This implies that your local firewall is blocking request to amazon…Ideally you should be fine without this section
//WebProxy proxyObject = new WebProxy(“myproxy.domain.com”, 8080);
//proxyObject.Credentials = new NetworkCredential(“*********”, “***********”);
//request.Proxy = proxyObject;

#endregion

//Set the request timeout to be 20sec
request.Timeout = 20000;

WebResponse response = request.GetResponse();
XmlReader reader = XmlReader.Create(response.GetResponseStream());

//Load the XDocument object with the response
responseDocument = XDocument.Load(reader);
}
catch (Exception ex)
{
throw new Exception(“Error consuming the Web Service at InvokeService(string requestUrl) Method | Message:” + ex.Message);
}

//Return the response XML results
return responseDocument;
}

The responseDocument would be the “ItemLookupResponse” XML, similar to the browser screenshot i showed earlier in this post.

There quite a handful of libraries in different programming languages that are available here, which you can use to sign your URL. Most of them are methods that accept your Access ID Key, Access Secret Key, Associate ID, the unsigned URL as inputs and return the signed URL as the output.

Run the finally constructed Signed URL in your browser to see the product data.

You could even test this using a Scratchpad application which amazon provides. The link to Scratchpad: http://associates-amazon.s3.amazonaws.com/scratchpad/index.html

The screenshot is as shown below:

Amazon API - ScratchPad

 

I hope this post gave you a quick start to consuming Amazon Product Advertising API and helped your development efforts.
Feel free to post your queries here.

WebRequest.GetResponse() throwing SSL secure channel error


Problem Statement:

WebRequest.GetResponse() is one of the most common ways we adopt to perform a HTTPWebRequest from our server side. This case was a specific one, although the error appeared to be more generic in nature. In fact it happened only in SharePoint and not in my .Net application.

The error observed in the GetResponse() method was:

“The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel”

One of the root cause of this problem is due to the certificate issue. And to be more precise the certificate validation has failed.

Solution:

The solution to this problem, more or less i would call it a decent workaround is to use the ServerCertificateCallbackValidation method from the HttpWebRequest class and forcefully return true.

Create a static method for validating the certificate

private static bool ValidateFbCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors)
{
return true;
}

Just before u make your HttpWebRequest try using this.

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidateFbCertificate);

HttpWebRequest …..;

This should skip any certificate errors.

Happy Coding!!!

Convert a JSON string into a C# object


There could be scenarios in our project wherein we consume a service which returns back a JSON message. These JSON message is infact a stringified version of an object and are recognized as a simple string format by our server side. Decoding them gets difficult at the first shot.

But C# itself has got a solution for this. And that is the JavaScriptSerializer object from the namespace System.Web.Script.Serialization;

Let me take you through the conversion of a JSON string to a custom C# object here. Its pretty simple!!

#1: ADD the following namespace to your code

Using System.Web.Script.Serialization;

#2: INITIALIZE the JavaScriptSerializer object

JavaScriptSerializer jss= new JavaScriptSerializer();

#3: IMPLEMENT the Deserialize method of JavaScriptSerializer, passing two important information – one is the custom object (MyCustomObject) and the JSON string (jsonResponse)

MyCustomObject user = jss.Deserialize<MyCustomObject>(jsonResponse);

#4: DEFINE the MyCustomObject class in your code. Ensure that the object structure matches the JSON string format.

public class MyCustomObject

{

public string myProperty1;

public string myProperty2;

}

You can then use the Deserialized object “user” and get its properties like:
user.Property1 or user.Property2.

For information on the Serialization of C# object to JSON, you can refer my previous post:

Generate JSON String Output in C#

 

Happy Coding!!!

Generate JSON string output in C#


This is one of the most widely used and very useful script that you could use in your web services/ WCF services/ Handlers or any place wherein you require a JSON string to be passed to the client/ consumer.

We make use of the Serialize method in JavaScriptSerializer class in C# under the following namespace:

using System.Web.Script.Serialization;

The code snippet below show how its done:

//Namespace for the JavascriptSerializer object

using System.Web.Script.Serialization;

public string GenerateJSONString(List<myObject> myCustomList)

{

//Initialize the JavascriptSerializer object   

JavaScriptSerializer serializer = new JavaScriptSerializer();

//Initialize a stringbuilder object to hold the final JSON output     

StringBuilder jsonBuilder = new StringBuilder();

//Generate the JSON string

serializer.Serialize(myCustomList, jsonBuilder);

//Return the JSON string

return Convert.ToString(jsonBuilder);

}

This code is just a framework to get to know that the JavascriptSerializer could help you generate JSON string with ease.

In the client side, you could use jQuery.parseJSON(JSONstring); and then parse this JSON string using the myObject properties. Remeber that parseJSON was added in jQuery v1.4.1.

Convert ‘\\’ to ‘\’ in c#


This post would sound pretty weird to any c# developer. However, a situation i had been in last week forced me to bring this into notice.

I had an XML file in which i had node values like ‘Requirements Management\XYZ’. I read the XML using XLinq and the c# string looked like ‘Requirements Management\\XYZ’. At first i felt its fine, as C# compiler added that extra backslash to handle an escape sequence. But when i tried using this value (stored in a variable), it was always returning me the string with ‘\\’. 😛

After 4 hours of trial and error, i found the solution. Believe it or not, i tried the extreme of exploiting the ‘Split’ and ‘Replace’ methods string gives me. 😛

Solution:

Whenever you need to assign this variable to some object property, in my case Area Path and Iteration Path for my TFS 2010 SDK API, you just need to make use of the powerful ‘@’ operator & String.Format method

string strXyz = Xdoc..Load(“myXML.xml”).Element(“abc”).Value; //This returned ‘Requirements Management\\XYZ’

Now to use this:

Obj.XYZ = String.Format(@”{0}”,strXyz); //The string value assigned to my ‘Obj’ object will be ‘Requirements Management\XYZ’.

It doesn’t make much sense, but this will handle the conversion of the double slashes to slash conversion.

But if you are using strings all the way, there’s nothing to worry, C# compiler will handle such situations. For instance displaying it on a textbox or some label or something.

Ideally you cannot convert double slashes to single slashes.. 🙂

When Microsoft or Google CDN fails, what should u do?


//

Let me tell you one thing, an outage in CDN is very rare. But just in case you don’t want to take a risk, go ahead with this fallback mechanism, as suggested by Scott Guru.
Microsoft CDN outage for jQuery:
<script type=”text/javascript”>
if (typeof jQuery == ‘undefined’)
{
document.write(unescape(“%3Cscript src=’/Scripts/jquery-1.4.2.min.js’ type=’text/javascript’%3E%3C/script%3E”));
}
</script>
Microsoft CDN outage for AJAX:

<script src=”http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js&#8221; type=”text/javascript”></script>
<script src=”http://ajax.microsoft.com/ajax/mvc/1.0/MicrosoftMvcAjax.js&#8221; type=”text/javascript”></script>
<script type=”text/javascript”>
if (typeof Sys == ‘undefined’)
{
document.write(unescape(“%3Cscript src=’/Scripts/MicrosoftAjax.js’ type=’text/javascript’%3E%3C/script%3E”));
document.write(unescape(“%3Cscript src=’/Scripts/MicrosoftMvcAjax.js’ type=’text/javascript’%3E%3C/script%3E”));
}
</script>
Use it for any CDN’s.
Let your mind be at peace.. 🙂

//

Coma getting added in a textbox, placed inside an update panel, on prefill


Problem:

A comma is getting appended to a textbox (textbox needs to be inside an update panel), each time a partial refresh happens in that page.

Solution:

The issue happened especially when i was populating the textbox, from the query string. Most importantly duplicate entries in the query string. 

ex: www.xyz.com?id=123 & val=rrq & id =  & nxt_Val=12

The id is repeating in the above query string. And the same value is populated in the textbox. In this case, the textbox will have the value prefilled as 123,  with a comma getting appended. This is normal and the issue is because of the duplicate id in the querystring. While prefilling the textbox with Request.QueryString[“id”] a comma gets added. Just avoid duplicate querystring keys to solve this issue.

Hope this helps.