i am trying to search in amazon product database with the following code posted in amazon webservice sample codes page
AWSECommerceService ecs = new AWSECommerceService();
// Create ItemSearch wrapper
ItemSearch search = new ItemSearch();
search.AssociateTag = "ABC";
search.AWSAccessKeyId = "XYZ";
// Create a request object
ItemSearchRequest request = new ItemSearchRequest();
// Fill request object with request parameters
request.ResponseGroup = new string[] { "ItemAttributes" };
// Set SearchIndex and Keywords
request.SearchIndex = "All";
request.Keywords = "The Shawshank Redemption";
// Set the request on the search wrapper
search.Request = new ItemSearchRequest[] { request };
try
{
//Send the request and store the response
//in response
ItemSearchResponse response = ecs.ItemSearch(search);
gvRes.DataSource = response.Items;
}
catch (Exception ex)
{
divContent.InnerText = ex.Message;
}
and getting the following error
The request must contain the parameter
Signature.
and amazon documentation is not clear about how to sign the requests.
any idea how to make it work???
thx
There's a helper class for REST called SignedRequestHelper.
You call it like so:
SignedRequestHelper helper =
new SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION);
requestUrl = helper.Sign(querystring);
There must be a similar one for SOAP calls in the above links.
i transcribed this vb code and it works for me
add the service reference and name it Amazon
http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl
go into the folder where your project is hosted, open the service reference folder and open the Reference.cs, then replace all the occurrences of [][] with [], next open AWSECommerceService.wsdl and find
<xs:element minOccurs="0" maxOccurs="unbounded" name="ImageSets">
and replace with
<xs:element minOccurs="0" maxOccurs="1" name="ImageSets">
add the following, and you'll need to manually reference some dlls
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Text.RegularExpressions;
using System.Xml;
using System.IO;
using System.Runtime.Serialization;
using AmazonApiTest.Amazon; //instead of AmazonApiTest use your project name
first various interface implementations
public class AmazonSigningMessageInspector : IClientMessageInspector
{
private string accessKeyId = "";
private string secretKey = "";
public AmazonSigningMessageInspector(string accessKeyId, string secretKey)
{
this.accessKeyId = accessKeyId;
this.secretKey = secretKey;
}
public Object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
{
string operation = Regex.Match(request.Headers.Action, "[^/]+$").ToString();
DateTime now = DateTime.UtcNow;
String timestamp = now.ToString("yyyy-MM-ddTHH:mm:ssZ");
String signMe = operation + timestamp;
Byte[] bytesToSign = Encoding.UTF8.GetBytes(signMe);
Byte[] secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
HMAC hmacSha256 = new HMACSHA256(secretKeyBytes);
Byte[] hashBytes = hmacSha256.ComputeHash(bytesToSign);
String signature = Convert.ToBase64String(hashBytes);
request.Headers.Add(new AmazonHeader("AWSAccessKeyId", accessKeyId));
request.Headers.Add(new AmazonHeader("Timestamp", timestamp));
request.Headers.Add(new AmazonHeader("Signature", signature));
return null;
}
void IClientMessageInspector.AfterReceiveReply(ref System.ServiceModel.Channels.Message Message, Object correlationState)
{
}
}
public class AmazonSigningEndpointBehavior : IEndpointBehavior
{
private string accessKeyId = "";
private string secretKey = "";
public AmazonSigningEndpointBehavior(string accessKeyId, string secretKey)
{
this.accessKeyId = accessKeyId;
this.secretKey = secretKey;
}
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new AmazonSigningMessageInspector(accessKeyId, secretKey));
}
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatched)
{
}
public void Validate(ServiceEndpoint serviceEndpoint)
{
}
public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParemeters)
{
}
}
public class AmazonHeader : MessageHeader
{
private string m_name;
private string value;
public AmazonHeader(string name, string value)
{
this.m_name = name;
this.value = value;
}
public override string Name
{
get { return m_name; }
}
public override string Namespace
{
get { return "http://security.amazonaws.com/doc/2007-01-01/"; }
}
protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteString(value);
}
}
now you use the generated code in this way
ItemSearch search = new ItemSearch();
search.AssociateTag = "YOUR ASSOCIATE TAG";
search.AWSAccessKeyId = "YOUR AWS ACCESS KEY ID";
ItemSearchRequest req = new ItemSearchRequest();
req.ResponseGroup = new string[] { "ItemAttributes" };
req.SearchIndex = "Books";
req.Author = "Lansdale";
req.Availability = ItemSearchRequestAvailability.Available;
search.Request = new ItemSearchRequest[]{req};
Amazon.AWSECommerceServicePortTypeClient amzwc = new Amazon.AWSECommerceServicePortTypeClient();
amzwc.ChannelFactory.Endpoint.EndpointBehaviors.Add(new AmazonSigningEndpointBehavior("ACCESS KEY", "SECRET KEY"));
ItemSearchResponse resp = amzwc.ItemSearch(search);
foreach (Item item in resp.Items[0].Item)
Console.WriteLine(item.ItemAttributes.Author[0] + " - " + item.ItemAttributes.Title);
try this one.. i hope it'll help.. i try and it works.. please share it with others.
download the sample code on http://www.falconwebtech.com/post/Using-WCF-and-SOAP-to-Send-Amazon-Product-Advertising-API-Signed-Requests
we need to update service references, make little change at app.config, program.cs, and reference.cs.
app.config:
(1.) appSettings tag;
assign accessKeyId and secretKey value,
add .
(2.) behaviours tag -> endpointBehaviors tag -> behaviour tag -> signingBehavior tag;
assign accessKeyId and secretKey value.
(3.) bindings tag -> basicHttpBinding tag; (optional)
delete binding tag except AWSECommerceServiceBindingNoTransport
and AWSECommerceServiceBindingTransport.
(4.) client tag;
delete endpoint tag except AWSECommerceServiceBindingTransport.
program.cs:
add itemSearch.AssociateTag = ConfigurationManager.AppSettings["associateTag"]; before ItemSearchResponse response = amazonClient.ItemSearch(itemSearch);
reference.cs: (open file in service references folder using visual studio)
change private ImageSet[][] imageSetsField; to private ImageSet[] imageSetsField;
change public ImageSet[][] ImageSets {...} to public ImageSet[] ImageSets {...}
finally we can run our program and it will work. good luck..
nb: there will be 1 warning (invalid child element signing behaviour), i think we can ignore it, or if you have any solution please share.. ^^v..