Amazon AWS ProtocolException - c#

I developed a web app using ASP .NET MVC3.
I'm trying to get book info using Amazon AWS based on ASIN.
This is the code snippet that should to that:
AsinRequest req = new AsinRequest();
req.asin = "0596158106";
req.type = "lite";
req.tag = "webservices-20";
req.devtag = "XXXXXXXXXXXX";
req.mode = "books";
req.locale = "US";
req.offer = "1";
req.offerpage = "1";
AmazonSearchPortClient amazonWS = new AmazonSearchPortClient();
ProductInfo prod = amazonWS.AsinSearchRequest(req);
Debug.WriteLine(prod.Details);
Every time I try to run it I get a HTTP 417 Expectation failed saying that it's a ProtocolException.
Instead of the X's I used the Access Key ID found in the Security Credentials section. I also tried using the Secret Access Key but it didn't make any difference.
I used this tutorial as a starting point:
http://channel9.msdn.com/coding4fun/articles/Using-the-Amazon-Web-Service
Does anyone know what could be causing it ?

Related

using the exmple of google drive sdk for read spreadsheet

I am trying to use the google drive sdk exmple for read spread sheet.
when I am opening the example I am getting this error: "unhandled excption has occured......... returned unexpected result"404"
I am doing the following things:
1) in the login section I am entering my user name and password correctly (validate it a couple of times that it is correct)
2) go to tab :"Selected SpreadSheet". then the error comes up
The problem you are experiencing is similar to this question: Google drive API to C#
You can no longer log into Google Spreadsheets with the old user credentials (username/password only). You need to use OAuth 2.0 now (which requires you to create an app and credentials at console.developers.google.com).
You can use the example below for the authentication logic, and use the logic in the logic found in this question to actually manipulate the file:
Accessing Google Spreadsheets with C# using Google Data API
Here is my answer to the linked question in case it gets deleted in the future:
This example requires you to use the following nuget packages and their dependencies:
Google.GData.Spreadsheets
Also, you must go to https://console.developers.google.com and register your application and create credentials for it so you can enter your CLIENT_ID and CLIENT_SECRET.
This is the documentation I used to put together this example: https://developers.google.com/google-apps/spreadsheets/
using System;
using System.Windows.Forms;
using Google.GData.Client;
using Google.GData.Spreadsheets;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
string CLIENT_ID = "YOUR_CLIENT_ID";
string CLIENT_SECRET = "YOUR_CLIENT_SECRET";
string SCOPE = "https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
OAuth2Parameters parameters = new OAuth2Parameters();
parameters.ClientId = CLIENT_ID;
parameters.ClientSecret = CLIENT_SECRET;
parameters.RedirectUri = REDIRECT_URI;
parameters.Scope = SCOPE;
string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
MessageBox.Show(authorizationUrl);
Console.WriteLine("Please visit the URL in the message box to authorize your OAuth "
+ "request token. Once that is complete, type in your access code to "
+ "continue...");
parameters.AccessCode = Console.ReadLine();
OAuthUtil.GetAccessToken(parameters);
string accessToken = parameters.AccessToken;
Console.WriteLine("OAuth Access Token: " + accessToken);
GOAuth2RequestFactory requestFactory =
new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v1", parameters);
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;
SpreadsheetQuery query = new SpreadsheetQuery();
SpreadsheetFeed feed = service.Query(query);
// Iterate through all of the spreadsheets returned
foreach (SpreadsheetEntry entry in feed.Entries)
{
// Print the title of this spreadsheet to the screen
Console.WriteLine(entry.Title.Text);
}
Console.ReadLine();
}
}
}

Digitally Sign SOAP Service Reference

I've been bagging my head for over a week with this. I've requested help from several Microsoft friends, but still no luck.
We are developing an online conference registration portal which requires online payments.
Unfortunately our Customer does not accept any other payment method other than a local (Chilean) payment Gateway (Transbank's WebPay Plus).
We tried to get them onboard with PayPal and several other's, but they would not accept for several reasons. So...we are stuck with WebPay Plus (WPP).
WPP accepts a SOAP request to initiate the transaction. But the request has to be digitally signed.
We have created the web reference and we are able to reach the server end, but we have not figured out how to digitally sign the request.
WPP requires us to créate a certificate with OpenSSL, which we did (oneclick.crt).
This is our code:
System.ServiceModel.Channels.Binding _binding = new BasicHttpBinding();
EndpointAddress _endpointAddress = new EndpointAddress("http://201.238.207.131:7003/WSWebpayTransaction/cxf/WSWebpayService");
ServiceReference3.WSWebpayServiceClient ws3 = new ServiceReference3.WSWebpayServiceClient(_binding, _endpointAddress);
ws3.Endpoint.Behaviors.Add(new CustomEndpointBehavior());
var _certificatePath = "~/oneclick.crt".ToAbsolutePath();
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(_certificatePath);
apiTransbank.ClientCertificates.Add(cert);
ws3.ClientCredentials.ClientCertificate.Certificate = cert;
var tI = new ServiceReference3.wsInitTransactionInput();
tI.wSTransactionType = ServiceReference3.wsTransactionType.TR_NORMAL_WS;
tI.sessionId = "xmsbs_calculate";
tI.returnURL = "http://www.test.cl";
tI.finalURL = "http://www.test.cl/final";
tI.transactionDetails = new[] {
new ServiceReference3.wsTransactionDetail()
{
amount = 1,
commerceCode = "XXXXXXXXXX",
buyOrder = "1000"
}
};
var _output = ws3.initTransaction(tI);
This request gives me the following response: "An error was discovered processing the header".
I have talked to WPP Support and the only thing they are wiling to say is that the request is not digitally signed.
So now we need to digitally sign this request and I cannot find anywhere how to do this (at least in a way I can understand, with clear code examples).

Calling MailChimp API v3.0 with .Net

I'm trying to access our MailChimp account via the new 3.0 REST API. I've done the following:
using(var http = new HttpClient())
{
var creds = Convert.ToBase64String(Encoding.ASCII.GetBytes("username:mailchimpapikey-us1"));
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", creds);
string content = await http.GetStringAsync(#"https://us1.api.mailchimp.com/3.0/lists");
Console.WriteLine(content);
}
However, when I run this code, I get a 401 error with the following json details:
{"type":"http://kb.mailchimp.com/api/error-docs/401-api-key-invalid","title":"API Key Invalid","status":401,"detail":"Your API key may be invalid, or you've attempted to access the wrong datacenter.","instance":"a9fe4028-519e-41d6-9f77-d2caee4d4683"}
The datacenter I'm using in my URI (us1 in this example) matches the dc on my API key. My API key works if I use the MailChimp SDK so I know my key isn't invalid. Also, using Fiddler, I can see that the MailChimp SDK is calling the same dc as I'm doing in my URI.
Any Ideas as to why I am having trouble Authenticating?
EDIT
As noted in the question, I'm asking specifically about accessing the new 3.0 REST API. I'm trying to do this directly as opposed to using a third party wrapper.
The new API is composed of http calls so it should be pretty straight forward. I'm simply having trouble with the authentication piece.
So I was able to finally chat with a super tech support person at MailChimp.
The MailChimp docs state the following
The easiest way to authenticate is using HTTP Basic Auth. Enter any string
as the username and supply your API Key as the password.
Your HTTP library should have built-in support for basic authorization.
Their documentation is a bit misleading. Typically the Auth header for Basic Auth would look like what I was sending:
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
where the row of x would represent the base64 encoded username:password.
However, talking with the support tech, the actual implementation they use is:
Authorization: username keyid
No base64 encoding, no Basic keyword. Username doesn't even have to be your username.
So, here is the working code:
using(var http = new HttpClient())
{
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", mailchimpapikey-us1);
string content = await http.GetStringAsync(#"https://us1.api.mailchimp.com/3.0/lists");
Console.WriteLine(content);
}
EDIT
Note the comments. TooMuchPete was correct in that the normal HTTP Basic Auth headers do work. Apparently I was hitting some old code or something on the MailChimp side.
I'm leaving the post as a reference for anyone who is trying to call the new 3.0 API.
I wrote an article on a simple way up adding subscribers to a list using:
Dim mailchimp As New ZmailChimp
Dim ListId$ = "9b2e63f0b9" 'List Sage' List
Dim email$ = "samsmith20#anymail.com" '"sam19#postcodelite.com"
Dim fieldListOnAdd = "FNAME,Sam,LNAME,Smith,MTYPE,User,MID,631637"
Dim fieldListOnUpdate = "FNAME,Sam,LNAME,Smith,MID,631637" 'Don't change MTYPE
'Put on 'Sage One' and 'Sage 50' group
Dim groupList = "407da9f47d,05086211ba"
With mailchimp
.API$ = "46cMailChimpAPIKeyd1de-us14" 'MailChimp API key
.dataCenter$ = "us14" 'Last 4 letters of API key
.password$ = "Password!"
MsgBox(.addSubscriber(ListId$, email, fieldListOnAdd, fieldListOnUpdate, groupList))
End With
mailchimp = Nothing
see:http://www.codeproject.com/Tips/1140339/Mail-Chimp-Add-Update-e-mail-to-List-and-Subscribe
this may save someone some time
Mailchimp Ecommerce
var mcorder = new Standup.Ecomm.MailChimpManager(ConfigurationManager.AppSettings["MailChimpApiKey"]);
var orders = new MailOrder();
orders.CampaignId = ConfigurationManager.AppSettings["MailChimpCampaignId"];
orders.EmailId = ConfigurationManager.AppSettings["MailChimpEmailId"];
orders.Id = orderNumber;
orders.StoreId = "abcde";
orders.StoreName = "E-Commerce Store";
orders.Total = Convert.ToDouble(orderTotal);
orders.Tax = Convert.ToDouble(tax);
orders.Items = new List<MailOrderItem>();
foreach (var orderItem in orderItemList)
{
var item = new MailOrderItem();
item.ProductId = orderItem.OrderNumber;
item.ProductName = orderItem.Title;
item.SKU = orderItem.Sku;
item.CategoryId = 0;
item.CategoryName = " ";
item.Quantity = orderItem.Quantity;
item.Cost = Convert.ToDouble(orderItem.ProductCost);
orders.Items.Add(item);
}
mcorder.AddOrder(orders);

Facebook C# SDK trouble getting me/accounts

I'm trying to write a windows service that will post to my Facebook Page with results when it runs.
I just downloaded Facebook C# SDK v6.0.10.0 and writing the windows application in .Net 4.0
I created a facebook application account and got the AppID and Secret code needed.
The end goal would be to have this windows service post on my facebook page wall as the page and not the application user.
I keep getting an error when I go to get the accounts for my facebook application.
string strAppID = "my app api id";
string strSecret = "my app secret code";
Facebook.FacebookClient fbClient = new Facebook.FacebookClient();
fbClient.AppId = strAppID;
fbClient.AppSecret = strSecret;
dynamic ac = fbClient.Get("oauth/access_token", new
{
client_id = strAppID,
client_secret = strSecret,
grant_type = "client_credentials"
});
string strAccessToken = String.Empty;
strAccessToken = ac.access_token;
if (!String.IsNullOrEmpty(strAccessToken))
{
fbClient = new Facebook.FacebookClient(strAccessToken);
fbClient.AccessToken = strAccessToken;
fbClient.AppId = strAppID;
fbClient.AppSecret = strSecret;
//Here is where it is bombing
dynamic fbAccounts = fbClient.Get("/me/accounts");
fbClient = new Facebook.FacebookClient(strAccessToken);
fbClient.AccessToken = strAccessToken;
fbClient.AppId = strAppID;
fbClient.AppSecret = strSecret;
dynamic me = fbClient.Get("**Name of the facebook page I am trying to post to**");
string strPageID = String.Empty;
strPageID = me.id;
string strPageAccessToken = String.Empty;
//Loop over the accounts looking for the ID that matches your destination ID (Fan Page ID)
foreach (dynamic account in fbAccounts.data)
{
if (account.id == strPageID)
{
//When you find it, grab the associated access token and put it in the Dictionary to pass in the FB Post, then break out.
strPageAccessToken = account.access_token;
break;
}
}
try
{
fbClient.AccessToken = strPageAccessToken;
var args = new Dictionary<string, object>();
args["message"] = "Testing 123";
fbClient.Post("/" + strPageID + "/feed", args);
}
catch (Facebook.FacebookOAuthException ex)
{
// oauth exception occurred
}
catch (Facebook.FacebookApiLimitException ex)
{
// api limit exception occurred.
}
catch (Facebook.FacebookApiException ex)
{
// other general facebook api exception
}
catch (Exception ex)
{
// non-facebook exception such as no internet connection.
}
}
The error I am getting is on the line:
dynamic fbAccounts = fbClient.Get("/me/accounts");
(OAuthException - #2500) An active access token must be used to query information about the current user.
see here: (OAuthException - #2500) An active access token must be used to query information about the current user
you are getting access token for the APPLICATION, not for a user.
Therefore, "me" does not make sense. You should supply ID there -
either your user ID, or your app ID, or any other ID your app has
permissions for.
dynamic ac = fbClient.Get("oauth/access_token", new
{
client_id = strAppID,
client_secret = strSecret,
grant_type = "client_credentials"
});
The above code may not work for version 6.0.
OAuth 2.0 - exchange code for access token
FacebookClient supports parsing only json responses. Due to this
reason “oauth/access_token” token will not work when using
FacebookClient.Get(“oauth/access_token”). Instead you will need to use
a method in FacebookOAuthClient.
You can find more details here: http://blog.prabir.me/post/Facebook-CSharp-SDK-Making-Requests.aspx
Hope this helps.

Accessing GData Calender from Google Apps account?

I'm building a simple app too that needs to access a calendar that's in my Google Apps account. But I'm having problems with authentication. I've tried the following code but it doesn't work:
Service service = new Service("<appname>");
service.setUserCredentials("<email>", "<password>");
CalendarEntry entry = (CalendarEntry)service.Get("<eventUrl>");
How do you get this to work with Google Apps? Is there any other type of authentication that I have to use for Google apps?
Update:
Unlocking the captcha solved my problem with getting the feed. Now I've hit the next wall: updating an event.
entry.Title.Text = "Foo";
entry.Update();
Gives me the GDataRequestException exception: "Can not update a read-only entry".
Im using the private calendar xml address that I got under kalendarsettings:
https://www.google.com/calendar/feeds/_%40group.calendar.google.com/private-/basic
I would recommend using Fiddler to see what http response you are getting back from Google. When I ran your code against my google apps account, I was getting back an "Error=CaptchaRequired" response. This required that I go to https://www.google.com/a/yourgoogleappdomain.com/UnlockCaptcha (replacing with your domain obviously). After I did that I was able to properly connect. You may be getting a different error code too so check for that and post it here. You could have an invalid password or invalid url or this functionality is disabled by your google apps administrator. Here is my sample code:
var calendarService = new CalendarService("company-app-version");
calendarService.setUserCredentials("<email>", "<password>");
var eventQuery = new EventQuery("http://www.google.com/calendar/feeds/user%40domain.com/private/full");
var eventFeed = calendarService.Query(eventQuery);
foreach (var atomEntry in eventFeed.Entries)
{
Console.WriteLine(atomEntry.Title.Text);
}
Make sure to replace the email, password, and email inside of the URL (url encode the # sign too).
using Google.GData.Client;
public bool ValidateGoogleAccount(string login, string password)
{
try
{
Service bloggerService = new Service("blogger", "App-Name");
bloggerService.Credentials = new GDataCredentials(login, password);
string token = bloggerService.QueryAuthenticationToken();
if (token != null)
return true;
else
return false;
}
catch (Google.GData.Client.InvalidCredentialsException)
{
return false;
}
}
Yet another solution Austin from google provides (it worked for me):
http://groups.google.com/group/google-calendar-help-dataapi/browse_thread/thread/400104713435a4b4?pli=1

Categories