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

| 我正在尝试使用亚马逊网络服务样本代码页面中发布的以下代码在亚马逊产品数据库中进行搜索
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;
}
并得到以下错误   该请求必须包含参数   签名。 并且亚马逊文档尚不清楚如何签署请求。 任何想法如何使其工作??? 谢谢     
已邀请:
REST有一个名为SignedRequestHelper的帮助程序类。 您这样称呼它:
SignedRequestHelper helper =
        new SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION);
requestUrl = helper.Sign(querystring);
在以上链接中,对于SOAP调用必须有一个类似的名称。     
我转录了这个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);
    
试试这个。.希望对您有帮助。.我尝试并且有效..请与他人分享。 在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.)绑定标签-> basicHttpBinding标签; (可选的)   删除除AWSECommerceServiceBindingNoTransport之外的绑定标签   和AWSECommerceServiceBindingTransport。 (4.)客户标签;   删除除AWSECommerceServiceBindingTransport之外的端点标记。 program.cs:   添加itemSearch.AssociateTag = ConfigurationManager.AppSettings [\“ associateTag \”];在ItemSearchResponse响应= amazonClient.ItemSearch(itemSearch)之前; reference.cs :(使用Visual Studio在服务引用文件夹中打开文件)   更改私有ImageSet [] [] imageSetsField;私有的ImageSet [] imageSetsField;   将public ImageSet [] [] ImageSet {...}更改为public ImageSet [] ImageSets {...} 最后,我们可以运行我们的程序,它将起作用。祝好运.. nb:将会有1条警告(无效的子元素签名行为),我认为我们可以忽略它,或者如果您有任何解决方案,请分享.. ^^ v ..     

要回复问题请先登录注册