3

Amazon Webサービスのサンプルコードページに投稿された次のコードを使用して、Amazon製品データベースで検索しようとしています

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

次のエラーが表示されます

リクエストにはパラメータ Signature が含まれている必要があります。

Amazon のドキュメントでは、リクエストに署名する方法が明確ではありません。

それを機能させる方法はありますか?

どうも

4

3 に答える 3

3

私はこの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);
于 2013-12-07T15:43:03.337 に答える
2

SignedRequestHelper という REST 用のヘルパー クラスがあります。

あなたはそれを次のように呼びます:

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

上記のリンクには、SOAP 呼び出し用の同様のものがあるはずです。

于 2011-04-26T19:38:02.820 に答える
1

これを試してみてください..役立つことを願っています..試してみるとうまくいきます..他の人と共有してください.

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 タグ -> basicHttpBinding タグ; (オプション) AWSECommerceServiceBindingNoTransport と AWSECommerceServiceBindingTransport 以外のバインディング タグを削除します。 (4.)クライアントタグ。AWSECommerceServiceBindingTransport 以外のエンドポイント タグを削除します。

program.cs: itemSearch.AssociateTag = ConfigurationManager.AppSettings["associateTag"]; を追加します。ItemSearchResponse レスポンスの前 = amazonClient.ItemSearch(itemSearch);

reference.cs: (Visual Studio を使用してサービス参照フォルダー内のファイルを開きます) change private ImageSet[][] imageSetsField; プライベート ImageSet[] imageSetsField へ。 public ImageSet [][] ImageSets {...} を public ImageSet[] ImageSets {...} に変更します

最後に、プログラムを実行して動作させることができます。幸運を..

注意: 1 つの警告 (無効な子要素の署名動作) が表示されます。無視してもよいと思います。または、解決策があれば共有してください..^^v..

于 2012-05-24T08:49:10.460 に答える