亚马逊产品广告API签名问题

本文关键字:问题 API 亚马逊 | 更新日期: 2023-09-27 17:53:37

我试图在亚马逊产品数据库搜索与以下代码张贴在亚马逊webservice示例代码页

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;
}

并得到以下错误

请求必须包含该参数签名。

和amazon文档都不清楚如何签署请求。

你知道怎么让它工作吗?

thx

亚马逊产品广告API签名问题

我转录了这个vb代码,它为我工作

添加服务引用并将其命名为Amazon

http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl

进入项目所在的文件夹,打开服务引用文件夹并打开reference .cs,然后将所有出现的[][]替换为[],然后打开AWSECommerceService。WSDL和查找

<xs:element minOccurs="0" maxOccurs="unbounded" name="ImageSets">

并替换为

<xs:element minOccurs="0" maxOccurs="1" name="ImageSets">

添加以下内容,您需要手动引用一些dll

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

第一种接口实现

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);
    }
}

现在您以这种方式使用生成的代码

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);

有一个REST的帮助类叫做SignedRequestHelper。

你这样称呼它:

SignedRequestHelper helper =
        new SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION);
requestUrl = helper.Sign(querystring);

上述链接中的SOAP调用必须有一个类似的

试试这个…我希望这对你有帮助。我试过了,它起作用了……请与他人分享。

在http://www.falconwebtech.com/post/Using-WCF-and-SOAP-to-Send-Amazon-Product-Advertising-API-Signed-Requests上下载样例代码

我们需要更新服务引用,在app.config、program.cs和reference.cs做一点改动。

app.config:(1) appSettings标签;分配accessKeyId和secretKey值,添加。(2.)行为标签-> endpointBehaviors标签->行为标签-> signingBehavior标签;分配accessKeyId和secretKey值。(3.) bindings tag -> basicHttpBinding tag;(可选)删除除AWSECommerceServiceBindingNoTransport之外的绑定标签和AWSECommerceServiceBindingTransport。(4.) client tag;删除AWSECommerceServiceBindingTransport之外的端点标签

program.cs: 添加itemSearch。AssociateTag = ConfigurationManager.AppSettings[" AssociateTag "];

reference.cs:(使用visual studio在service references文件夹中打开文件)change private ImageSet[][] imageSetsField;private ImageSet[] imageSetsField;change public ImageSet[][] ImageSets{…} to public ImageSet[] ImageSet{…}

最后,我们可以运行我们的程序,它将工作。祝你好运. .

注意:会有1个警告(无效的子元素签名行为),我想我们可以忽略它,或者如果你有任何解决方案请分享。^ ^ v . .