C# CurlSharp EasyGet - How to get string result - c#

I'm using this code to make an EasyGet request.Does anyone know how to get a string result?
using CurlSharp;
public static void CurlSharpGet(string url, bool useHttp2 = true)
{
Curl.GlobalInit(CurlInitFlag.All);
try
{
if (useHttp2)
{
using (var easy = new CurlEasy())
{
easy.Url = url;
easy.WriteFunction = OnWriteData;
easy.HttpVersion = CurlHttpVersion.Http2_0;
easy.SslVerifyPeer = false;
easy.SslVerifyhost = false;
easy.Perform();
Console.WriteLine(easy.Perform());
}
}
else
{
using (var easy = new CurlEasy())
{
easy.Url = url;
easy.WriteFunction = OnWriteData;
easy.Perform();
Console.WriteLine(easy.Perform());
}
}
}
finally
{
Curl.GlobalCleanup();
}
}
public static Int32 OnWriteData(byte[] buf, Int32 size, Int32 nmemb, object data)
{
Console.Write(Encoding.UTF8.GetString(buf));
return size * nmemb;
}
Ideally i would like to have something that looks like this:
public static string CurlSharpGet(string url, bool useHttp2 = true)
{
//my fixed code here
}
The nature of what I'm doing cannot be accomplished using httpclient or webresponse. Would appreciate any advice on what I should do to get the above code to return a string result. Thanks

Related

Return newtonsoft json object from WebMethod

I want to return a JSON object from a c# webmethod if i use return i have an error "recussive reference found". So i decided to use newtonsoft serialize but the returned object are in double quote. {d:"my json"} and didn't work.
I try to use this code :
[WebMethod(EnableSession = true)]
public static void RecordList(int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
string error;
var result = DataTools.Data("select id_individu,nom_indiv from individu limit 10",
WebConfigurationManager.ConnectionStrings["TabloidConnection"].ConnectionString,
out error);
var rep = System.Web.HttpContext.Current.Response;
rep.Clear();
rep.ClearContent();
rep.BufferOutput = true;
rep.ContentType = "application/json; charset=UTF-8";
//rep.Write("ab");
rep.Write("{d:");
rep.Write(JsonConvert.SerializeObject(new jTableResponse(result), Formatting.None));
rep.Write("}");
rep.Flush();
//rep.SuppressContent = true;
rep.End();
//ct.ApplicationInstance.CompleteRequest();
}
public class jTableResponse
{
private int totalRecordCount=0;
private DataTable records;
private string result = "OK";
public string Result
{
get { return result; }
set { result = value; }
}
public int TotalRecordCount
{
get { return totalRecordCount; }
set { totalRecordCount = value; }
}
public DataTable Records
{
get { return records; }
set { records = value; }
}
public jTableResponse(DataTable r)
{
Records = r;
totalRecordCount = r.Rows.Count;
}
}
But i have character added behind and after my json like this (using fiddler)
1d0
{d:{"Result":"OK","TotalRecordCount":10,"Records":[{"id_individu":1,"nom_indiv":"..."},{"id_individu":2,"nom_indiv":"RIVET"},{"id_individu":3,"nom_indiv":"COHEN"},{"id_individu":4,"nom_indiv":"VILLEROUGE"},{"id_individu":5,"nom_indiv":"CAILLARD"},{"id_individu":6,"nom_indiv":"DE CHEVRON VILLETTE"},{"id_individu":7,"nom_indiv":"ROYO"},{"id_individu":8,"nom_indiv":"ROQUES"},{"id_individu":9,"nom_indiv":"GUILLOT"},{"id_individu":10,"nom_indiv":"DORNE-CORRAZE"}]}}
0
Thanks for your response
When i change this
rep.Write("{d:");
rep.Write(JsonConvert.SerializeObject(new jTableResponse(result), Formatting.None));
rep.Write("}");
by this
rep.Write(JsonConvert.SerializeObject(new jTableResponse(result), Formatting.None));
it work fine thanks.

Xamarin Android: Save Facebook Access Token in strings.xml

I've searched on google on how to dynamically edit the Resources.Values.strings.xml file so I can add my Facebook Access Token so the user won't need to log in again when he reuses the app.
Is it possible to edit it, or do I have to use another method to store the token?
I think the best place would be to save this to the KeyStore. To do this you must use the DependencyService More Info here
The interface and implementation would then be:
PCL interface
public interface IAuth
{
void CreateStore();
IEnumerable<string> FindAccountsForService(string serviceId);
void Save(string pin,string serviceId);
void Delete(string serviceId);
}
Android
public class IAuthImplementation : IAuth
{
Context context;
KeyStore ks;
KeyStore.PasswordProtection prot;
static readonly object fileLock = new object();
const string FileName = "MyProg.Accounts";
static readonly char[] Password = null;
public void CreateStore()
{
this.context = Android.App.Application.Context;
ks = KeyStore.GetInstance(KeyStore.DefaultType);
prot = new KeyStore.PasswordProtection(Password);
try
{
lock (fileLock)
{
using (var s = context.OpenFileInput(FileName))
{
ks.Load(s, Password);
}
}
}
catch (Java.IO.FileNotFoundException)
{
//ks.Load (null, Password);
LoadEmptyKeyStore(Password);
}
}
public IEnumerable<string> FindAccountsForService(string serviceId)
{
var r = new List<string>();
var postfix = "-" + serviceId;
var aliases = ks.Aliases();
while (aliases.HasMoreElements)
{
var alias = aliases.NextElement().ToString();
if (alias.EndsWith(postfix))
{
var e = ks.GetEntry(alias, prot) as KeyStore.SecretKeyEntry;
if (e != null)
{
var bytes = e.SecretKey.GetEncoded();
var password = System.Text.Encoding.UTF8.GetString(bytes);
r.Add(password);
}
}
}
return r;
}
public void Delete(string serviceId)
{
var alias = MakeAlias(serviceId);
ks.DeleteEntry(alias);
Save();
}
public void Save(string pin, string serviceId)
{
var alias = MakeAlias(serviceId);
var secretKey = new SecretAccount(pin);
var entry = new KeyStore.SecretKeyEntry(secretKey);
ks.SetEntry(alias, entry, prot);
Save();
}
void Save()
{
lock (fileLock)
{
using (var s = context.OpenFileOutput(FileName, FileCreationMode.Private))
{
ks.Store(s, Password);
}
}
}
static string MakeAlias(string serviceId)
{
return "-" + serviceId;
}
class SecretAccount : Java.Lang.Object, ISecretKey
{
byte[] bytes;
public SecretAccount(string password)
{
bytes = System.Text.Encoding.UTF8.GetBytes(password);
}
public byte[] GetEncoded()
{
return bytes;
}
public string Algorithm
{
get
{
return "RAW";
}
}
public string Format
{
get
{
return "RAW";
}
}
}
static IntPtr id_load_Ljava_io_InputStream_arrayC;
void LoadEmptyKeyStore(char[] password)
{
if (id_load_Ljava_io_InputStream_arrayC == IntPtr.Zero)
{
id_load_Ljava_io_InputStream_arrayC = JNIEnv.GetMethodID(ks.Class.Handle, "load", "(Ljava/io/InputStream;[C)V");
}
IntPtr intPtr = IntPtr.Zero;
IntPtr intPtr2 = JNIEnv.NewArray(password);
JNIEnv.CallVoidMethod(ks.Handle, id_load_Ljava_io_InputStream_arrayC, new JValue[]
{
new JValue (intPtr),
new JValue (intPtr2)
});
JNIEnv.DeleteLocalRef(intPtr);
if (password != null)
{
JNIEnv.CopyArray(intPtr2, password);
JNIEnv.DeleteLocalRef(intPtr2);
}
}
Call Create Store in the main activity of Android app first. - This could possibly be improved and remove CreateStrore() from the interface by checking if ks == null in Save and Delete and calling the method if true
This would then save the access token to the KeyStore that you can then retrieve later

Correct way to store encryption key for SqlCipher database

I have a Xamarin application and have managed to download my data from my server to my device. I have also got it set up so that it can take a SqlCipher Encryption key to encrypt the data.
My question is where is the correct location to store my key that I use to encrypt this data? Is it to you KeyStore / KeyChain? Which mono classes should I be looking to use?
Due to the popularity of this question I am going to post my implementation of this:
PCL interface
public interface IAuth
{
void CreateStore();
IEnumerable<string> FindAccountsForService(string serviceId);
void Save(string pin,string serviceId);
void Delete(string serviceId);
}
Android
public class IAuthImplementation : IAuth
{
Context context;
KeyStore ks;
KeyStore.PasswordProtection prot;
static readonly object fileLock = new object();
const string FileName = "MyProg.Accounts";
static readonly char[] Password = null;
public void CreateStore()
{
this.context = Android.App.Application.Context;
ks = KeyStore.GetInstance(KeyStore.DefaultType);
prot = new KeyStore.PasswordProtection(Password);
try
{
lock (fileLock)
{
using (var s = context.OpenFileInput(FileName))
{
ks.Load(s, Password);
}
}
}
catch (Java.IO.FileNotFoundException)
{
//ks.Load (null, Password);
LoadEmptyKeyStore(Password);
}
}
public IEnumerable<string> FindAccountsForService(string serviceId)
{
var r = new List<string>();
var postfix = "-" + serviceId;
var aliases = ks.Aliases();
while (aliases.HasMoreElements)
{
var alias = aliases.NextElement().ToString();
if (alias.EndsWith(postfix))
{
var e = ks.GetEntry(alias, prot) as KeyStore.SecretKeyEntry;
if (e != null)
{
var bytes = e.SecretKey.GetEncoded();
var password = System.Text.Encoding.UTF8.GetString(bytes);
r.Add(password);
}
}
}
return r;
}
public void Delete(string serviceId)
{
var alias = MakeAlias(serviceId);
ks.DeleteEntry(alias);
Save();
}
public void Save(string pin, string serviceId)
{
var alias = MakeAlias(serviceId);
var secretKey = new SecretAccount(pin);
var entry = new KeyStore.SecretKeyEntry(secretKey);
ks.SetEntry(alias, entry, prot);
Save();
}
void Save()
{
lock (fileLock)
{
using (var s = context.OpenFileOutput(FileName, FileCreationMode.Private))
{
ks.Store(s, Password);
}
}
}
static string MakeAlias(string serviceId)
{
return "-" + serviceId;
}
class SecretAccount : Java.Lang.Object, ISecretKey
{
byte[] bytes;
public SecretAccount(string password)
{
bytes = System.Text.Encoding.UTF8.GetBytes(password);
}
public byte[] GetEncoded()
{
return bytes;
}
public string Algorithm
{
get
{
return "RAW";
}
}
public string Format
{
get
{
return "RAW";
}
}
}
static IntPtr id_load_Ljava_io_InputStream_arrayC;
void LoadEmptyKeyStore(char[] password)
{
if (id_load_Ljava_io_InputStream_arrayC == IntPtr.Zero)
{
id_load_Ljava_io_InputStream_arrayC = JNIEnv.GetMethodID(ks.Class.Handle, "load", "(Ljava/io/InputStream;[C)V");
}
IntPtr intPtr = IntPtr.Zero;
IntPtr intPtr2 = JNIEnv.NewArray(password);
JNIEnv.CallVoidMethod(ks.Handle, id_load_Ljava_io_InputStream_arrayC, new JValue[]
{
new JValue (intPtr),
new JValue (intPtr2)
});
JNIEnv.DeleteLocalRef(intPtr);
if (password != null)
{
JNIEnv.CopyArray(intPtr2, password);
JNIEnv.DeleteLocalRef(intPtr2);
}
}
Call Create Store in the main activity of Android app first. - This could possibly be improved and remove CreateStrore() from the interface by checking if ks == null in Save and Delete and calling the method if true
iOS
public class IAuthImplementation : IAuth
{
public IEnumerable<string> FindAccountsForService(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
SecStatusCode result;
var records = SecKeyChain.QueryAsRecord(query, 1000, out result);
return records != null ?
records.Select(GetAccountFromRecord).ToList() :
new List<string>();
}
public void Save(string pin, string serviceId)
{
var statusCode = SecStatusCode.Success;
var serializedAccount = pin;
var data = NSData.FromString(serializedAccount, NSStringEncoding.UTF8);
//
// Remove any existing record
//
var existing = FindAccount(serviceId);
if (existing != null)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
statusCode = SecKeyChain.Remove(query);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not save account to KeyChain: " + statusCode);
}
}
//
// Add this record
//
var record = new SecRecord(SecKind.GenericPassword);
record.Service = serviceId;
record.Generic = data;
record.Accessible = SecAccessible.WhenUnlocked;
statusCode = SecKeyChain.Add(record);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not save account to KeyChain: " + statusCode);
}
}
public void Delete(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
var statusCode = SecKeyChain.Remove(query);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not delete account from KeyChain: " + statusCode);
}
}
string GetAccountFromRecord(SecRecord r)
{
return NSString.FromData(r.Generic, NSStringEncoding.UTF8);
}
string FindAccount(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
SecStatusCode result;
var record = SecKeyChain.QueryAsRecord(query, out result);
return record != null ? GetAccountFromRecord(record) : null;
}
public void CreateStore()
{
throw new NotImplementedException();
}
}
WP
public class IAuthImplementation : IAuth
{
public IEnumerable<string> FindAccountsForService(string serviceId)
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
string[] auths = store.GetFileNames("MyProg");
foreach (string path in auths)
{
using (var stream = new BinaryReader(new IsolatedStorageFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, store)))
{
int length = stream.ReadInt32();
byte[] data = stream.ReadBytes(length);
byte[] unprot = ProtectedData.Unprotect(data, null);
yield return Encoding.UTF8.GetString(unprot, 0, unprot.Length);
}
}
}
}
public void Save(string pin, string serviceId)
{
byte[] data = Encoding.UTF8.GetBytes(pin);
byte[] prot = ProtectedData.Protect(data, null);
var path = GetAccountPath(serviceId);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, store))
{
stream.WriteAsync(BitConverter.GetBytes(prot.Length), 0, sizeof(int)).Wait();
stream.WriteAsync(prot, 0, prot.Length).Wait();
}
}
public void Delete(string serviceId)
{
var path = GetAccountPath(serviceId);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
store.DeleteFile(path);
}
}
private string GetAccountPath(string serviceId)
{
return String.Format("{0}", serviceId);
}
public void CreateStore()
{
throw new NotImplementedException();
}
}
This is an adaptation of the Xamarin.Auth library (Found Here) but removes the dependency from the Xamarin.Auth library to provide cross platform use through the interface in the PCL. For this reason I have simplified it to only save one string. This is probably not the best implementation but it works in my case. Feel free to expand upon this
There is a nuget package called KeyChain.NET that encapsulated this logic for iOs, Android and Windows Phone.
It's open source and you have find sample at its github repository
More info at this blog post

itunes listening to

within windows live messenger, it is possible to share the song you are currently listening to. what would i need to do to get this working within c# like libarys etc cannot find the correct documentation on google.
You'll need to use the iTunes SDK to interact with iTunes from .NET. So there's your Google search term. :)
Here's a start:
http://blogs.msdn.com/b/noahc/archive/2006/07/06/automating-itunes-with-c-in-net.aspx
http://blogs.msdn.com/b/dancre/archive/2004/05/08/128645.aspx
Here is a script for LinqPad in C# which does as requested. (see LinqPad.com)
Bonus! Artwork view.
It looks like this:
<Query Kind="Program">
<Namespace>iTunesLib</Namespace>
<Namespace>System.Security.Cryptography</Namespace>
</Query>
void Main()
{
var track = new iTunesApp().CurrentTrack;
if (track == null)
"nothing playing".Dump();
else
new Viewer(track,true).Dump();
}
public class Viewer
{
const string PREFIX = "itlps-";
private IITFileOrCDTrack store;
private bool materialize;
public string album { get { return store.Album; } }
public string band { get { return store.Artist; } }
public string song { get { return store.Name; } }
public string desc { get { return store.Description; } }
public int? artCnt { get {
if (store.Artwork == null) return null;
else return store.Artwork.Count; }
}
public IEnumerable<ImageViewer> art { get {
if (materialize)
{
foreach(var artT in store.Artwork)
{
var art = artT as IITArtwork;
string ext = ".tmp";
switch(art.Format)
{
case ITArtworkFormat.ITArtworkFormatBMP:
ext = ".BMP";
break;
case ITArtworkFormat.ITArtworkFormatJPEG:
ext = ".JPG";
break;
case ITArtworkFormat.ITArtworkFormatPNG:
ext = ".PNG";
break;
}
string path = Path.Combine(Path.GetTempPath(),PREFIX+Path.GetRandomFileName()+ext);
art.SaveArtworkToFile(path);
yield return new ImageViewer(path);
}
}
yield break; }
}
public Viewer(IITFileOrCDTrack t,bool materializeArt = false)
{
store = t;
materialize = materializeArt;
}
public Viewer(IITTrack t,bool materializeArt = false)
{
store = t as IITFileOrCDTrack;
materialize = materializeArt;
}
}
public class ImageViewer
{
public string hash { get { return _hash.Value; } }
static private string _path { get; set; }
public object image { get { return _image.Value; } }
static private SHA1Managed sha = new SHA1Managed();
private Lazy<object> _image = new Lazy<object>(() => {return Util.Image(_path);});
private Lazy<string> _hash = new Lazy<string>(() =>
{
string hash = string.Empty;
using (FileStream stream = File.OpenRead(_path))
{
byte [] checksum = sha.ComputeHash(stream);
hash = BitConverter.ToString(checksum).Replace("-", string.Empty);
}
return hash;
});
public ImageViewer(string path)
{
_path = path;
}
}
last i checked this functionality is included out of the box all you need is to have itunes and windows live messenger installed and activate "what im listening to" and it shows this in your messenger status. if you are looking to create a bot that messages this out to a contact that is a different story tho that you will need to write a script for

amazon product advertising api - item lookup request working example

would anyone have a working example of an amazon ITEMLOOKUP ?>
i have the following code but it does not seem to work:
string ISBN = "0393326381";
string ASIN = "";
if (!(string.IsNullOrEmpty(ISBN) && string.IsNullOrEmpty(ASIN)))
{
AWSECommerceServicePortTypeChannel service = new AWSECommerceServicePortTypeChannel();
ItemLookup lookup = new ItemLookup();
ItemLookupRequest request = new ItemLookupRequest();
lookup.AssociateTag = secretKey;
lookup.AWSAccessKeyId = accessKeyId;
if (string.IsNullOrEmpty(ASIN))
{
request.IdType = ItemLookupRequestIdType.ISBN;
request.ItemId = new string[] { ISBN.Replace("-", "") };
}
else
{
request.IdType = ItemLookupRequestIdType.ASIN;
request.ItemId = new string[] { ASIN };
}
request.ResponseGroup = new string[] { "OfferSummary" };
lookup.Request = new ItemLookupRequest[] { request };
response = service.ItemLookup(lookup);
if (response.Items.Length > 0 && response.Items[0].Item.Length > 0)
{
Item item = response.Items[0].Item[0];
if (item.MediumImage == null)
{
//bookImageHyperlink.Visible = false;
}
else
{
//bookImageHyperlink.ImageUrl = item.MediumImage.URL;
}
//bookImageHyperlink.NavigateUrl = item.DetailPageURL;
//bookTitleHyperlink.Text = item.ItemAttributes.Title;
//bookTitleHyperlink.NavigateUrl = item.DetailPageURL;
if (item.OfferSummary.LowestNewPrice == null)
{
if (item.OfferSummary.LowestUsedPrice == null)
{
//priceHyperlink.Visible = false;
}
else
{
//priceHyperlink.Text = string.Format("Buy used {0}", item.OfferSummary.LowestUsedPrice.FormattedPrice);
//priceHyperlink.NavigateUrl = item.DetailPageURL;
}
}
else
{
//priceHyperlink.Text = string.Format("Buy new {0}", item.OfferSummary.LowestNewPrice.FormattedPrice);
//priceHyperlink.NavigateUrl = item.DetailPageURL;
}
if (item.ItemAttributes.Author != null)
{
//authorLabel.Text = string.Format("By {0}", string.Join(", ", item.ItemAttributes.Author));
}
else
{
//authorLabel.Text = string.Format("By {0}", string.Join(", ", item.ItemAttributes.Creator.Select(c => c.Value).ToArray()));
}
/*
ItemLink link = item.ItemLinks.Where(i => i.Description.Contains("Wishlist")).FirstOrDefault();
if (link == null)
{
//wishListHyperlink.Visible = false;
}
else
{
//wishListHyperlink.NavigateUrl = link.URL;
}
* */
}
}
}
the problem is with this:
thisshould be defined differently but i do not know how AWSECommerceServicePortTypeChannel service = new AWSECommerceServicePortTypeChannel();
Say, that code looks awful familiar. You're missing the Endpoint signing piece from when they switched over to requiring that you add message signing. You need to add a behavior on your client. Here's the change to your code above:
if (!(string.IsNullOrEmpty(ISBN) && string.IsNullOrEmpty(ASIN)))
{
AWSECommerceServicePortTypeClient client = new AWSECommerceServicePortTypeClient();
client.ChannelFactory.Endpoint.Behaviors.Add(
new Amazon.AmazonSigningEndpointBehavior(
accessKeyId,
secretKey);
ItemLookup lookup = new ItemLookup();
ItemLookupRequest request = new ItemLookupRequest();
lookup.AssociateTag = accessKeyId;
lookup.AWSAccessKeyId = secretKey;
//... etc.
And here's the Endpoint (I can't take credit for this, I wish I could remember who should):
namespace Amazon
{
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.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; }
}
}
Oh. And you'll need the MessageInspector for that to work.
namespace Amazon
{
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) { }
}
}
And finally, the Header:
namespace Amazon
{
public class AmazonHeader : MessageHeader
{
private string name;
private string value;
public AmazonHeader(string name, string value)
{
this.name = name;
this.value = value;
}
public override string Name { get { return name; } }
public override string Namespace { get { return "http://security.amazonaws.com/doc/2007-01-01/"; } }
protected override void OnWriteHeaderContents(XmlDictionaryWriter xmlDictionaryWriter, MessageVersion messageVersion)
{
xmlDictionaryWriter.WriteString(value);
}
}
}
Yes, they made it complicated when they started requiring message signing...
A simple and easy library is available on nuget.
PM> Install-Package Nager.AmazonProductAdvertising
Example
var authentication = new AmazonAuthentication("accesskey", "secretkey");
var client = new AmazonProductAdvertisingClient(authentication, AmazonEndpoint.US);
var result = await client.GetItemsAsync("B00BYPW00I");
To perform a lookup for anything other then an ASIN, you need to specify the "SearchIndex" property. You can simply set it to "All".
var request = new ItemLookupRequest();
request.ItemId = new[] {upcCode};
request.IdType = ItemLookupRequestIdType.UPC;
request.IdTypeSpecified = true;
request.SearchIndex = "All";
Here is a link to the documentation: http://docs.amazonwebservices.com/AWSECommerceService/2011-08-01/DG/index.html?ItemLookup.html. Note the description of the SearchIndex parameter:
Constraint:If ItemIdis an ASIN, a search index cannot be specified in
the request. Required for non-ASIN ItemIds.
I actually built a little wrapper around it so it hands you back a handy object graph. I have the source up on BitBucket and a little more about it on the C# Amazon ItemLookup page.
C# Amazon ItemLookup
You can make calls like:
var item = client.LookupByAsin("B0037X9N5U");
double? price = item.GetLowestPrice();

Categories