मैं इसके साथ भी संघर्ष कर रहा हूं (और मैं सीखने के चरण में भी हूं)।
जो मैंने पाया वह सबसे अच्छा काम करता था, आरईएसटी एपीआई का उपयोग करना था, और उसके बाद परिणामों को लिंक से एक्सएमएल के साथ एक कस्टम परिणाम ऑब्जेक्ट में पार्स करना था जिसके साथ मैं काम कर सकता था। लंबे कोड पेस्ट क्षमा करें (इस बोर्ड पर प्रोटोकॉल पर यकीन नहीं है) लेकिन लगा कि आप इसे सब चाहते हैं। इनमें से अधिकांश अमेज़ॅन के अपने नमूने में से एक आया था, लेकिन वहां साइट व्यवस्थित नहीं है इसलिए मैं इसे फिर से ढूंढने के लिए संघर्ष कर रहा हूं।
// custom class for result item
public class AmazonBookSearchResult
{
public string ASIN;
public string Author;
public string Title;
public Uri DetailPageURL;
public Uri AllCustomerReviews;
}
// I call this with the search terms, returns an IEnumerable of results
public class ItemLookup
{
private const string MY_AWS_ACCESS_KEY_ID = "YOUR KEY";
private const string MY_AWS_SECRET_KEY = "YOUR KEY";
private const string DESTINATION = "ecs.amazonaws.com";
private const string NAMESPACE = "http://webservices.amazon.com/AWSECommerceService/2009-03-31";
public static IEnumerable<AmazonBookSearchResult> AmazonItemLookup(string category, string browseNode, string keyWords)
{
SignedRequestHelper helper = new SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION);
String requestUrl;
IDictionary<string, string> r1 = new Dictionary<string, String>();
r1["Service"] = "AWSECommerceService";
r1["Version"] = "2009-03-31";
r1["Operation"] = "ItemSearch";
r1["ResponseGroup"] = "ItemAttributes";
r1["SearchIndex"] = category;
r1["Keywords"] = keyWords;
requestUrl = helper.Sign(r1);
XmlDocument xmlDoc = sendRequest(requestUrl);
XDocument doc = XDocument.Load(new XmlNodeReader(xmlDoc));
XNamespace ns = "http://webservices.amazon.com/AWSECommerceService/2009-03-31";
IEnumerable<AmazonBookSearchResult> result =
from items in doc.Element(ns + "ItemSearchResponse").Elements(ns + "Items").Elements(ns + "Item")
select new AmazonBookSearchResult
{
ASIN = (string)items.Element(ns + "ASIN")
};
int count = doc.Element(ns + "ItemSearchResponse").Elements(ns + "Items").Elements(ns + "Item").Count();
return result;
} // end Lookup()
// this is just taken from the amazon sample
private static XmlDocument sendRequest(string url)
{
try
{
WebRequest request = HttpWebRequest.Create(url);
WebResponse response = request.GetResponse();
XmlDocument doc = new XmlDocument();
doc.Load(response.GetResponseStream());
XmlNodeList errorMessageNodes = doc.GetElementsByTagName("Message", NAMESPACE);
if (errorMessageNodes != null && errorMessageNodes.Count > 0)
{
String message = errorMessageNodes.Item(0).InnerText;
throw new Exception("Error " + message);
}
return doc;
}
catch (Exception e)
{
System.Console.WriteLine("Caught Exception: " + e.Message);
System.Console.WriteLine("Stack Trace: " + e.StackTrace);
}
return null;
}// end FetchTitle()
}
class SignedRequestHelper
{
private string endPoint;
private string akid;
private byte[] secret;
private HMAC signer;
private const string REQUEST_URI = "/onca/xml";
private const string REQUEST_METHOD = "GET";
/*
* Use this constructor to create the object. The AWS credentials are available on
* http://aws.amazon.com
*
* The destination is the service end-point for your application:
* US: ecs.amazonaws.com
* JP: ecs.amazonaws.jp
* UK: ecs.amazonaws.co.uk
* DE: ecs.amazonaws.de
* FR: ecs.amazonaws.fr
* CA: ecs.amazonaws.ca
*/
public SignedRequestHelper(string awsAccessKeyId, string awsSecretKey, string destination)
{
this.endPoint = destination.ToLower();
this.akid = awsAccessKeyId;
this.secret = Encoding.UTF8.GetBytes(awsSecretKey);
this.signer = new HMACSHA256(this.secret);
}
/*
* Sign a request in the form of a Dictionary of name-value pairs.
*
* This method returns a complete URL to use. Modifying the returned URL
* in any way invalidates the signature and Amazon will reject the requests.
*/
public string Sign(IDictionary<string, string> request)
{
// Use a SortedDictionary to get the parameters in naturual byte order, as
// required by AWS.
ParamComparer pc = new ParamComparer();
SortedDictionary<string, string> sortedMap = new SortedDictionary<string, string>(request, pc);
// Add the AWSAccessKeyId and Timestamp to the requests.
sortedMap["AWSAccessKeyId"] = this.akid;
sortedMap["Timestamp"] = this.GetTimestamp();
// Get the canonical query string
string canonicalQS = this.ConstructCanonicalQueryString(sortedMap);
// Derive the bytes needs to be signed.
StringBuilder builder = new StringBuilder();
builder.Append(REQUEST_METHOD)
.Append("\n")
.Append(this.endPoint)
.Append("\n")
.Append(REQUEST_URI)
.Append("\n")
.Append(canonicalQS);
string stringToSign = builder.ToString();
byte[] toSign = Encoding.UTF8.GetBytes(stringToSign);
// Compute the signature and convert to Base64.
byte[] sigBytes = signer.ComputeHash(toSign);
string signature = Convert.ToBase64String(sigBytes);
// now construct the complete URL and return to caller.
StringBuilder qsBuilder = new StringBuilder();
qsBuilder.Append("http://")
.Append(this.endPoint)
.Append(REQUEST_URI)
.Append("?")
.Append(canonicalQS)
.Append("&Signature=")
.Append(this.PercentEncodeRfc3986(signature));
return qsBuilder.ToString();
}
/*
* Sign a request in the form of a query string.
*
* This method returns a complete URL to use. Modifying the returned URL
* in any way invalidates the signature and Amazon will reject the requests.
*/
public string Sign(string queryString)
{
IDictionary<string, string> request = this.CreateDictionary(queryString);
return this.Sign(request);
}
/*
* Current time in IS0 8601 format as required by Amazon
*/
private string GetTimestamp()
{
DateTime currentTime = DateTime.UtcNow;
string timestamp = currentTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
return timestamp;
}
/*
* Percent-encode (URL Encode) according to RFC 3986 as required by Amazon.
*
* This is necessary because .NET's HttpUtility.UrlEncode does not encode
* according to the above standard. Also, .NET returns lower-case encoding
* by default and Amazon requires upper-case encoding.
*/
private string PercentEncodeRfc3986(string str)
{
str = HttpUtility.UrlEncode(str, System.Text.Encoding.UTF8);
str = str.Replace("'", "%27").Replace("(", "%28").Replace(")", "%29").Replace("*", "%2A").Replace("!", "%21").Replace("%7e", "~").Replace("+", "%20");
StringBuilder sbuilder = new StringBuilder(str);
for (int i = 0; i < sbuilder.Length; i++)
{
if (sbuilder[i] == '%')
{
if (Char.IsLetter(sbuilder[i + 1]) || Char.IsLetter(sbuilder[i + 2]))
{
sbuilder[i + 1] = Char.ToUpper(sbuilder[i + 1]);
sbuilder[i + 2] = Char.ToUpper(sbuilder[i + 2]);
}
}
}
return sbuilder.ToString();
}
/*
* Convert a query string to corresponding dictionary of name-value pairs.
*/
private IDictionary<string, string> CreateDictionary(string queryString)
{
Dictionary<string, string> map = new Dictionary<string, string>();
string[] requestParams = queryString.Split('&');
for (int i = 0; i < requestParams.Length; i++)
{
if (requestParams[i].Length < 1)
{
continue;
}
char[] sep = { '=' };
string[] param = requestParams[i].Split(sep, 2);
for (int j = 0; j < param.Length; j++)
{
param[j] = HttpUtility.UrlDecode(param[j], System.Text.Encoding.UTF8);
}
switch (param.Length)
{
case 1:
{
if (requestParams[i].Length >= 1)
{
if (requestParams[i].ToCharArray()[0] == '=')
{
map[""] = param[0];
}
else
{
map[param[0]] = "";
}
}
break;
}
case 2:
{
if (!string.IsNullOrEmpty(param[0]))
{
map[param[0]] = param[1];
}
}
break;
}
}
return map;
}
/*
* Consttuct the canonical query string from the sorted parameter map.
*/
private string ConstructCanonicalQueryString(SortedDictionary<string, string> sortedParamMap)
{
StringBuilder builder = new StringBuilder();
if (sortedParamMap.Count == 0)
{
builder.Append("");
return builder.ToString();
}
foreach (KeyValuePair<string, string> kvp in sortedParamMap)
{
builder.Append(this.PercentEncodeRfc3986(kvp.Key));
builder.Append("=");
builder.Append(this.PercentEncodeRfc3986(kvp.Value));
builder.Append("&");
}
string canonicalString = builder.ToString();
canonicalString = canonicalString.Substring(0, canonicalString.Length - 1);
return canonicalString;
}
}
/*
* To help the SortedDictionary order the name-value pairs in the correct way.
*/
class ParamComparer : IComparer<string>
{
public int Compare(string p1, string p2)
{
return string.CompareOrdinal(p1, p2);
}
}
अच्छा प्रश्न, बुरा उपयोगकर्ता नाम। –
धन्यवाद सर। मुझे लगता है कि यह एक उचित नाम है, यह देखते हुए कि मैं एक कोडर का कितना बुरा हूं। – asfsadf
अच्छा, वास्तव में नहीं, यह इंप्रेशन बनाता है कि आपकी मदद करने के लिए किसी का प्रयास उनके समय का अपशिष्ट होगा। "गुरुतुर्द" आज़माएं। यू के बहुत सारे, यह ठंडा है और अभी भी आपकी विशेषज्ञता पर संकेत देता है। –