Как мне вызвать API книги Amazon в C #?

1

Я пытаюсь запросить API книг Amazon Web Service (AWS) в С#. Я не читал связанные сообщения в Stackoverflow. Я все еще получаю сообщение об ошибке: "Удаленный сервер ответил на ошибку: (403) Запрещено". Я закодировал все + и =. Что я делаю неправильно здесь, пожалуйста?

    public const string ACCESSKEY = "xxxxx";  // Replace with Actual Access Key
    public const string SECRETKEY = "zzzzz";  // Replace with Actual Secret Key

    public void ProcessRequest(HttpContext context)
    {
        string ts = DateTime.UtcNow.ToString("s");

        string url = "http://webservices.amazon.com/onca/xml?";
        string req = "AWSAccessKeyId=" + ACCESSKEY + "&Condition=All&IdType=ASIN&ItemId=B00008OE6I&Operation=ItemLookup&ResponseGroup=OfferFull&Service=AWSECommerceService";
        req = req + "&Timestamp=" + URLEncode(ts + "Z").ToUpper();

        string s = "GET\nwebservices.amazon.com\n/onca/xml\n" + req;

        Util.Write(s);
        Util.Write("");

        string hash = HashString(s);
        req = req + "&Signature=" + hash;

        url = url + req;
        Util.Write(url);
        Util.Write("");

        string blob = XGetBlobAtURL(url);
        Util.Write(blob);

    }

    private string URLEncode(string s)
    {
        return(HttpContext.Current.Server.UrlEncode(s));
    }

    private string XGetBlobAtURL(string url, string useragent = "")
    {
        string blob = "";
        try
        {
            WebClient wc = new WebClient();
            if (!Util.IsEmpty(useragent)) { wc.Headers["User-Agent"] = useragent; }
            blob = wc.DownloadString(url);
            wc.Dispose();
        }
        catch(Exception e)
        {
            Util.Write(e.ToString());
        }
        return (blob);
    }

    private string HashString(string s)
    {
        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(URLEncode(SECRETKEY));

        HMACSHA256 hmasha256 = new HMACSHA256(keyByte);

        byte[] messageBytes = encoding.GetBytes(s);
        byte[] hashmessage = hmasha256.ComputeHash(messageBytes);
        string s2 = ByteToString(hashmessage); 

        return (URLEncode(s2));
    }

    private string ByteToString(byte[] buff)
    {
        string sbinary = "";
        for (int i = 0; i < buff.Length; i++)
        {
            sbinary += buff[i].ToString("X2"); // hex format
        }
        return (sbinary);
    }
  • 0
    Я обновил код после того, как понял, что я делаю неправильно. Мне нужно было: Base64 кодировать хеш HMASHA256, добавить недостающие поля в строке запроса в Amazon Book API и прописать URLEncoded% XX без заглавных букв в остальной части строки. Приведенный выше код теперь работает и соответствует документации Amazon по адресу: docs.aws.amazon.com/AWSECommerceService/latest/DG/…
  • 0
    Я переместил ваше решение в ответ сообщества вики.
Теги:
object
amazon-web-services
rest

1 ответ

0

Решение от OP.

Я понял, что я делаю неправильно. Мне пришлось: Base64 закодировать хэш HMASHA256, добавить отсутствующие поля в строке запроса в Amazon Book API и прописать верхний регистр URLEncoded% XX без верхнего конца остальной строки. Код, указанный ниже, теперь работает и соответствует документации Amazon по адресу: http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html

    public const string ACCESSKEY = "xxxxx";
    public const string SECRETKEY = "zzzzz";
    public const string TAG = "ccccc";

    private XmlDocument XML;

    public void ProcessRequest(HttpContext context)
    {
        string ts = DateTime.UtcNow.ToString("s");
        string url = "http://webservices.amazon.com/onca/xml?";
        string req = "AWSAccessKeyId=" + ACCESSKEY + "&AssociateTag=" + TAG;

        // Search by ISBN:
        req = req + "&Condition=All&IdType=ISBN&ItemId=0596004923&Operation=ItemLookup&ResponseGroup=Small&SearchIndex=Books&Service=AWSECommerceService";

        string tsq = "&Timestamp=" + URLEncode(ts + "Z").ToUpper();

        string s = "GET\nwebservices.amazon.com\n/onca/xml\n" + req + tsq;

        string hash = HashString(s);
        req = req + tsq + "&Signature=" + hash;

        url = url + req;

        ReadXML(url);
        WriteXML();
    }

    private void ReadXML(string url)
    {
        XML = new XmlDocument();
        XML.Load(url);
    }

    private void WriteXML()
    {
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.ContentType = "text/xml";
        HttpContext.Current.Response.CacheControl = "no-cache";
        HttpContext.Current.Response.Write(XML.OuterXml);
        HttpContext.Current.Response.End();
    }

    private string UCaseUrlEncode(string s)
    {
        char[] x = HttpUtility.UrlEncode(s).ToCharArray();
        for (int i = 0; i < x.Length - 2; i++)
        {
            if (x[i] == '%')
            {
                x[i+1] = char.ToUpper(x[i+1]);
                x[i+2] = char.ToUpper(x[i+2]);
            }
        }
        return new string(x);
    }

    private string URLEncode(string s)
    {
        return(HttpContext.Current.Server.UrlEncode(s));
    }

    private string URLDecode(string s)
    {
        return (HttpContext.Current.Server.UrlDecode(s));
    }

    private string HashString(string s)
    {
        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(SECRETKEY);
        byte[] messageBytes = encoding.GetBytes(s);

        HMACSHA256 hmasha256 = new HMACSHA256(keyByte);
        byte[] hashmessage = hmasha256.ComputeHash(messageBytes);
        return (UCaseUrlEncode(Convert.ToBase64String(hashmessage)));
    }

    private string ByteToString(byte[] buff)
    {
        string sbinary = "";
        for (int i = 0; i < buff.Length; i++)
        {
            sbinary += buff[i].ToString("X2"); // hex format
        }
        return (sbinary);
    }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню