亚马逊产品广告API ItemSearch返回空

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了亚马逊产品广告API ItemSearch返回空相关的知识,希望对你有一定的参考价值。

我花了一整天的时间来尝试解决Amazon ECS(电子商务服务)API的问题。

我已经在他们的站点上下载了用于使用.NET 4.0和WCF发送SOAP请求的示例

http://aws.amazon.com/code/Product-Advertising-API/3941

除了配置文件中的AccessKeyID和SecretyKeyID之外,我没有更改示例代码中的任何内容。

调用代码如下所示:

        // Instantiate Amazon ProductAdvertisingAPI client
        AWSECommerceServicePortTypeClient amazonClient = new AWSECommerceServicePortTypeClient();

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

        ItemSearch itemSearch = new ItemSearch();
        itemSearch.Request = new ItemSearchRequest[] { request };
        request.Condition = Condition.All;
        itemSearch.AssociateTag = "";
        itemSearch.AWSAccessKeyId = ConfigurationManager.AppSettings["accessKeyId"];

        // send the ItemSearch request
        ItemSearchResponse response = amazonClient.ItemSearch(itemSearch);
        if (response != null)
        {
            // write out the results from the ItemSearch request
            foreach (var item in response.Items[0].Item)
            {
                Console.WriteLine(item.ItemAttributes.Title);
            }
        }
        Console.WriteLine("done...enter any key to continue>");
        Console.ReadLine();

调用ItemSearch()返回一个null对象。我进一步研究了这一点,发现在AmazongSigningMessageInspector类中,AfterReceiveReply()方法显示正在返回带有结果的正确SOAP XML响应,因此我知道它正在调用服务并正确返回。出于某种原因,虽然我留下了一个NULL ItemSearch对象。

我的类的代码如下:

class AmazonSigningBehaviorExtensionElement : BehaviorExtensionElement
{
    public AmazonSigningBehaviorExtensionElement()
    {
    }

    public override Type BehaviorType
    {
        get
        {
            return typeof(AmazonSigningEndpointBehavior);
        }
    }

    protected override object CreateBehavior()
    {
        return new AmazonSigningEndpointBehavior(AccessKeyId, SecretKey);
    }

    [ConfigurationProperty("accessKeyId", IsRequired = true)]
    public string AccessKeyId
    {
        get { return (string)base["accessKeyId"]; }
        set { base["accessKeyId"] = value; }
    }

    [ConfigurationProperty("secretKey", IsRequired = true)]
    public string SecretKey
    {
        get { return (string)base["secretKey"]; }
        set { base["secretKey"] = value; }
    }
}


public class AmazonSigningEndpointBehavior : IEndpointBehavior {
    private string  _accessKeyId    = "";
    private string  _secretKey  = "";

    public AmazonSigningEndpointBehavior()
    {
        this._accessKeyId = ConfigurationManager.AppSettings["accessKeyId"];
        this._secretKey = ConfigurationManager.AppSettings["secretKey"];
    }

    public AmazonSigningEndpointBehavior(string accessKeyId, string secretKey) {
        this._accessKeyId   = accessKeyId;
        this._secretKey     = secretKey;
    }

    public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime) {
        clientRuntime.MessageInspectors.Add(new AmazonSigningMessageInspector(_accessKeyId, _secretKey));
    }

    public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) { return; }
    public void Validate(ServiceEndpoint serviceEndpoint) { return; }
    public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters) { return; }
}

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 Message request, IClientChannel channel) {
        // prepare the data to sign
        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);

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

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {


    }
}

我到处都看到了这个问题,但是没有人在任何地方发布过它的修复程序。有人请帮帮我。

答案

我的问题是我错过了关联标签。

itemSearch.AssociateTag = "213";

生成的代码肯定存在问题,ItemSearchResponse包含一个错误集合,不会被代码暴露。通过查看检查员中的原始信息,我指出了正确的方向。

另一答案

关于缺少关联标记的答案对我有帮助,但我还必须确保WSDL URL和端点地址与您注册的Amazon网站相匹配。我在英国网站注册,所以我需要使用。

WSDL Endpoint Address

另一答案

您可以在Nager.AmazonProductAdvertising github上找到此作业的当前项目。该图书馆也可在nuget上找到

掘金

PM> Install-Package Nager.AmazonProductAdvertising

var authentication = new AmazonAuthentication();
authentication.AccessKey = "accesskey";
authentication.SecretKey = "secretkey";

var wrapper = new AmazonWrapper(authentication, AmazonEndpoint.US);
var result = wrapper.Search("canon eos", AmazonSearchIndex.Electronics, AmazonResponseGroup.Large);
另一答案

我编译并发布了此示例的修复程序。请到这里:https://forums.aws.amazon.com/message.jspa?messageID=440527#440527

以上是关于亚马逊产品广告API ItemSearch返回空的主要内容,如果未能解决你的问题,请参考以下文章

带有流星的亚马逊产品 API

当请求 url 包含“!”时,亚马逊产品广告 API 返回“SignatureDoesNotMatch”

如何使用亚马逊的产品广告 API 获取运输信息

亚马逊产品广告 API - 获得评论排名

如何在我的 Rails 应用程序中与亚马逊产品广告 API 交互?

可以通过亚马逊产品广告 API 检索 Kindle 电子书的实际价格吗?