I have this code
DocumentsService vService = new DocumentsService("test");
vService.setUserCredentials("vUserName", "vPassword");
RequestSettings vSettings = new RequestSettings("test");
DocumentsRequest vDocReq = new DocumentsRequest(vSettings);
Feed<Document> vFeed = vDocReq.GetEverything();
foreach (Document d in vFeed.Entries) {
lbxDocumente.Items.Add(d.Title + " " + d.Author);
}
Why do I get this exception?
System.Net.WebException: The remote server returned an error: (401) Unauthorized
This line is trying to authenticate with the actual strings "vUserName" and "vPassword":
vService.setUserCredentials("vUserName", "vPassword");
Did you mean it to be this instead, in order to use variables which you've initialized elsewhere?
vService.setUserCredentials(vUserName, vPassword);
(What's with the v prefix, by the way? I generally don't like prefixes like this at all, but I've never even seen v as a prefix before...)
EDIT: You're also not associating the request with the service anywhere. I've tried this code, and it works fine:
DocumentsService service = new DocumentsService("test");
service.setUserCredentials(user, password);
RequestSettings settings = new RequestSettings("test");
DocumentsRequest docReq = new DocumentsRequest(settings);
docReq.Service = service;
Feed<Document> feed = docReq.GetEverything();
foreach (Document d in feed.Entries) {
Console.WriteLine(d.Title);
}
Related
The following code is used by software on a server outside AWS to obtain some information from a file within an S3 bucket in Amazon. This data is then broken up and used for other purposes.
List<Document> documentList = new List<Document>();
try
{
AmazonS3Config amazonS3Config = new AmazonS3Config();
amazonS3Config.RegionEndpoint = Amazon.RegionEndpoint.GetBySystemName(Settings.AWSRegion);
if (Settings.Proxy == true)
{
if (Settings.IsMasterService == true)
{
amazonS3Config.ProxyHost = Settings.ProxyHost;
amazonS3Config.ProxyPort = Settings.ProxyPort;
amazonS3Config.ProxyCredentials = System.Net.CredentialCache.DefaultCredentials;
}
else
{
if (Settings.IsCompanyStore == true)
{
amazonS3Config.ProxyHost = Settings.ProxyHostCompanyStore;
amazonS3Config.ProxyPort = Settings.ProxyPortCompanyStore;
NetworkCredential corpProxyCreds = new NetworkCredential(Settings.ProxyUserNameCompanyStore, Settings.ProxyPasswordCompanyStore);
amazonS3Config.ProxyCredentials = corpProxyCreds;
}
}
}
AmazonS3Client s3 = new AmazonS3Client(amazonCreds, amazonS3Config);
GetObjectRequest req = new GetObjectRequest();
req.BucketName = Settings.S3BucketName;
req.Key = Settings.S3ObjectName;
using (GetObjectResponse response = s3.GetObject(req))
if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
{
using (Stream amazonStream = response.ResponseStream)
{
StreamReader amazonStreamReader = new StreamReader(amazonStream);
string _lne = string.Empty;
while ((_lne = amazonStreamReader.ReadLine()) != null)
{
string[] _cfglines = _lne.Split('&');
foreach (string c in _cfglines)
{
string[] _fle = c.Split('|');
Document d = new Document();
d.Name = _fle[1];
d.FolderPath = _fle[0];
documentList.Add(d);
}
}
}
}
else
{
EventHandling.RaiseDebugEvent("response.HttpStatusCode.ToString() = " + response.HttpStatusCode.ToString());
throw new Exception("Could not obtain master configuration file. Status: " + response.HttpStatusCode.ToString());
}
}
catch (Exception ex)
{
EventHandling.RaiseDebugEvent(" ReturnCloudCaptureDocumentList ex.tostring = " + ex.ToString());
EventHandling.RaiseEvent(ex.Message, System.Diagnostics.EventLogEntryType.Error);
}
return documentList;
We have two different types of servers outside AWS. One behind a proxy, one not behind a proxy.
On the server not behind a proxy, this code works fine.
On the server behind a web proxy, this code fails every time with the following error:
'Error making request with Error Code ServiceUnavailable and Http
Status Code ServiceUnavailable. No further error information was
returned by the service.
Reviewing Amazon documentation, the ServiceUnavailable error occurs when you are making too many requests to S3 in a short space of time. This isn't true of this scenario however. We are making only one request, and even if we were making many requests, this would not explain why on one server it works fine, but on another it doesn't (with the only difference being the presence of a Proxy).
Any advice would be appreciated.
(Well shoot, if no one else wants the reputation, I'll take it. ;) )
There are at least three things I can think of (ht to #Collin-Dauphinee).
Access to the bucket may be restricted to the non-proxy'd machine's IP.
Your proxy may be mangling the request.
Your proxy may be refusing to forward the request.
I'm trying to develop a simple application that will enable users to purchase services off a website through the Paypal API. This application is running on ASP.NET with C#.
I have had very little luck trying to get the Paypal API to co-operate. The method I'm calling is SetExpressCheckout with all the appropriate variables.
I did my research and discovered that since I'm testing in Localhost, it may affect Paypal's ability to communicate with the application. So the next thing I tried was accessing my application through an open port and a publicly accessible IP address, but the same error occurs on the call to SetExpressCheckout.
Here is the error:
Exception Details: System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
Source Error:
Line 1790: [return: System.Xml.Serialization.XmlElementAttribute("SetExpressCheckoutResponse", Namespace="urn:ebay:api:PayPalAPI")]
Line 1791: public SetExpressCheckoutResponseType SetExpressCheckout([System.Xml.Serialization.XmlElementAttribute(Namespace="urn:ebay:api:PayPalAPI")] SetExpressCheckoutReq SetExpressCheckoutReq) {
Line 1792: object[] results = this.Invoke("SetExpressCheckout", new object[] {
Line 1793: SetExpressCheckoutReq});
Line 1794: return ((SetExpressCheckoutResponseType)(results[0]));
Source File: c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\anan_p2\730602d6\31a8d74e\App_WebReferences.c8vgyrf8.2.cs Line: 1792
I've also tried generating certificates using OpenSSL and uploading them to the Paypal account's encrypted seller option but still no effect.
Thank you very much for reading through my question!
Update: As requested here is the code being used.
String hostingOn = ConfigurationManager.AppSettings["default_site_url"];
reqDetails.ReturnURL = hostingOn + "marketplace_confirm.aspx";
reqDetails.CancelURL = hostingOn + "marketplace.aspx";
reqDetails.NoShipping = "1";
reqDetails.ReqConfirmShipping = "0";
reqDetails.OrderTotal = new BasicAmountType()
{
currencyID = CurrencyCodeType.CAD,
Value = payment_amt.Value,
};
SetExpressCheckoutReq req = new SetExpressCheckoutReq()
{
SetExpressCheckoutRequest = new SetExpressCheckoutRequestType()
{
Version = UtilPayPalAPI.Version,
SetExpressCheckoutRequestDetails = reqDetails
}
};
PayPalAPIAASoapBinding paypal = new PayPalAPIAASoapBinding();
paypal.SetExpressCheckout(req);
I am also using the https://api-aa-3t.paypal.com/2.0/ url for accessing the API
Since early 2016, Paypal started requiring TLS 1.2 protocol for communications in the Sandbox, and will enforce it for the live environment starting June 17. See here for reference.
In most .NET applications TLS 1.2 will come disabled by default, and therefore you'll need to enable it.
You need to add the following line, for example, at the beginning of you Application_Start method:
public class Site : HttpApplication
{
protected void Application_Start()
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// other configuration
}
}
You're probably connecting to api.paypal.com or api.sandbox.paypal.com, and not sending along your API certificate. The API certificate is a client SSL certificate used to complete the SSL chain.
If you don't have or are not using an API certificate, you should connect to api-3t.paypal.com or api-3t.sandbox.paypal.com for Live or Sandbox respectively.
I've been working with a PayPal (NVP/Signature) Express Checkout integration and have been hit with this SSL/TLS error.
Nothing I did seemed to get around it but then I found the following code to add above my request. For reference, I'm using MVC3/.NET 4 so Tls1.2 isn't available to me by default (like in .NET 4.5 +). This first three lines of this code gets around that. I hope it helps people!
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
ServicePointManager.DefaultConnectionLimit = 9999;
var url = "https://[paypal-api-url]/nvp";
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var encoding = new UTF8Encoding();
var requestData = encoding.GetBytes(data);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Timeout = (300 * 1000);
request.ContentLength = requestData.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(requestData, 0, requestData.Length);
}
var response = request.GetResponse();
...
Thanks a lot that really helps me.
For reference here is my code for establishing the interface in VB.NET
'Create a service Binding in code
Dim ppEndpointAddress As New System.ServiceModel.EndpointAddress("https://api-3t.sandbox.paypal.com/2.0/")
Dim ppBinding As New System.ServiceModel.BasicHttpBinding(System.ServiceModel.BasicHttpSecurityMode.Transport)
Dim ppIface As New PayPalAPI.PayPalAPIAAInterfaceClient(ppBinding, ppEndpointAddress)
Dim ppPaymentReq As New PayPalAPI.DoDirectPaymentReq()
ppPaymentReq.DoDirectPaymentRequest = ppRequest
I want to update the contents of the already uploaded Google Doc file.
I'm using the below code:
DocumentsService service = new DocumentsService("app-v1");
string auth = gLogin2();
service.SetAuthenticationToken(auth);
Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(
"CONTENTS PLEASE CHANGE"));
DocumentEntry entry = service.Update(new Uri("feedURL"), stream, "text/plain",
"nameOfDoc") as DocumentEntry;
For "feedURL" I tried using all the possible links: alternate, self, edit, edit-media even resumable-edit-media, but I keep on getting exceptions.
Also how do I read a response with such requests?
I just started using this API. Earlier, I was using it on the protocol level so was sending GET/POST requests and receiving web responses. I don't know how to get or read response in this case.
UPDATE:
Now the code I'm using is:
RequestSettings _settings;
string DocumentContentType = "text/html";
_settings = new RequestSettings("Stickies", "EMAIL", "PASSWORD");
var request = new DocumentsRequest(_settings);
//var entryToUpdate = doc.DocumentEntry;
var updatedContent = "new content..."; ;
var mediaUri = new Uri(string.Format(DocumentsListQuery.mediaUriTemplate, rid));
Trace.WriteLine(mediaUri);
var textStream = new MemoryStream(Encoding.UTF8.GetBytes(updatedContent));
var reqFactory = (GDataRequestFactory)request.Service.RequestFactory;
reqFactory.CustomHeaders.Add(string.Format("{0}: {1}", GDataRequestFactory.IfMatch, et));
var oldEtag = et;
DocumentEntry entry = request.Service.Update(mediaUri, textStream, DocumentContentType, title) as DocumentEntry;
Debug.WriteLine(string.Format("ETag changed while saving {0}: {1} -> {2}", title, oldEtag,et));
Trace.WriteLine("reached");
And the exception I'm getting is:
{"The remote server returned an error: (412) Precondition Failed."}
I'm getting this exception at DocumentEntry entry = request.Service.Update(mediaUri, textStream, DocumentContentType, title) as DocumentEntry;
Solved.. Exception precondition Failed was due to Etag mismatch
The above UPDATED code works perfectly for saving a document.
I'm trying to use OAuth for authentication for the FreshBooks API from my ASP.NET MVC C# app. Here is what I have so far:
I'm using DotNetOpenAuth here is the code I have in my controller action
if (TokenManager != null)
{
ServiceProviderDescription provider = new ServiceProviderDescription();
provider.ProtocolVersion = ProtocolVersion.V10a;
provider.AccessTokenEndpoint = new MessageReceivingEndpoint ("https://myfbid.freshbooks.com/oauth/oauth_access.php", DotNetOpenAuth.Messaging.HttpDeliveryMethods.PostRequest);
provider.RequestTokenEndpoint = new DotNetOpenAuth.Messaging.MessageReceivingEndpoint("https://myfbid.freshbooks.com/oauth/oauth_request.php", DotNetOpenAuth.Messaging.HttpDeliveryMethods.PostRequest);
provider.UserAuthorizationEndpoint = new DotNetOpenAuth.Messaging.MessageReceivingEndpoint("https://myfbid.freshbooks.com/oauth/oauth_authorize.php", DotNetOpenAuth.Messaging.HttpDeliveryMethods.GetRequest);
provider.TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() };
var consumer = new WebConsumer(provider, TokenManager);
var response = consumer.ProcessUserAuthorization();
if (response != null)
{
this.AccessToken = response.AccessToken;
}
else
{
// we need to request authorization
consumer.Channel.Send(consumer.PrepareRequestUserAuthorization(
new Uri("http://localhost:9876/home/testoauth/"), null, null));
}
}
The TokenManager is the same class that is provided with the DotNetOpenAuth sample, I've set my consumer secret that FreshBooks gave me.
On the consumer.Channel.Send(consumer.PrepareRequestUserAuthorization(...)) I've got the following exception:
"The remote server returned an error: (400) Bad Request.".
Am I doing this correctly? Based on FreshBooks documentation and DotNetOpenAuth samples that should work correctly.
Is there a simpler way to authenticate with OAuth, as DotNetOpenAuth is a bit huge for simply using OAuth authentication?
if you want to use DotNetOpenAuth you need to make sure that:
you use signature method "PLAINTEXT"
and use PlaintextSigningBindingElement as TamperProtectionElements
something like this works for me:
public static readonly ServiceProviderDescription ServiceDescription = new ServiceProviderDescription
{
ProtocolVersion = ProtocolVersion.V10a,
RequestTokenEndpoint = new MessageReceivingEndpoint(oAuthBase + "/oauth_request.php", HttpDeliveryMethods.PostRequest),
UserAuthorizationEndpoint = new MessageReceivingEndpoint(oAuthBase + "/oauth_authorize.php", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
AccessTokenEndpoint = new MessageReceivingEndpoint(oAuthBase + "/oauth_access.php", HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new PlaintextSigningBindingElement() }
};
public static void RequestAuthorization(WebConsumer consumer)
{
if (consumer == null)
{
throw new ArgumentNullException("consumer");
}
var extraParameters = new Dictionary<string, string> {
{ "oauth_signature_method", "PLAINTEXT" },
};
Uri callback = Util.GetCallbackUrlFromContext();
var request = consumer.PrepareRequestUserAuthorization(callback, extraParameters, null);
consumer.Channel.Send(request);
}
You could try using my open source OAuth Library. It's extremely simple to use and get going. I have a sample project that's available in the download that connects to Google, Twitter, Yahoo and Vimeo. I've intentionally kept the code very simple so it's easy to understand.
OAuth C# Library
I've not used FreshBooks, but it should be a simple matter of changing the url for one of the providers in the sample application and of course setting up provider specific keys etc.
I'm struggling with the final part of getting my first bit of code working with the AWS - I have got this far, I attached the web reference in VS and this have this
amazon.AWSECommerceService service = new amazon.AWSECommerceService();
// prepare an ItemSearch request
amazon.ItemSearchRequest request = new amazon.ItemSearchRequest();
request.SearchIndex = "DVD";
request.Title = "scream";
request.ResponseGroup = new string[] { "Small" };
amazon.ItemSearch itemSearch = new amazon.ItemSearch();
itemSearch.AssociateTag = "";
itemSearch.Request = new ItemSearchRequest[] { request };
itemSearch.AWSAccessKeyId = ConfigurationManager.AppSettings["AwsAccessKeyId"];
itemSearch.Request = new ItemSearchRequest[] { request };
ItemSearchResponse response = service.ItemSearch(itemSearch);
// write out the results
foreach (var item in response.Items[0].Item)
{
Response.Write(item.ItemAttributes.Title + "<br>");
}
I get the error
The request must contain the parameter Signature.
I know you have to 'sign' requests now, but can't figure out 'where' I would do this or how? any help greatly appreciated?
You have to add to the SOAP request headers including your Amazon access key ID, a timestamp, and the SHA256 hash of the request operation and the timestamp. To accomplish that, you would need access to the SOAP message just before it is going to be sent out. There's a walkthrough and a sample project I put together at http://flyingpies.wordpress.com/2009/08/01/17/.
For the record:
Another reason to get this error is due to keywords with spaces in it.
Example:
'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=xxx&AssociateTag=usernetmax-20&Version=2011-08-01&Operation=ItemSearch&ResponseGroup=Medium,Offers&SearchIndex=All&Keywords=Baby
Stroller&MerchantId=All&Condition=All&Availability=Available&ItemPage=1&Timestamp=2012-05-16T02:17:32Z&Signature=ye5c2jo99cr3%2BPXVkMyXX8vMhTC21UO4XfHpA21%2BUCs%3D'
It should be:
'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=xxx&AssociateTag=usernetmax-20&Version=2011-08-01&Operation=ItemSearch&ResponseGroup=Medium,Offers&SearchIndex=All&Keywords=Baby%20Stroller&MerchantId=All&Condition=All&Availability=Available&ItemPage=1&Timestamp=2012-05-16T02:17:32Z&Signature=ye5c2jo99cr3%2BPXVkMyXX8vMhTC21UO4XfHpA21%2BUCs%3D'
PHP solution:
$Keywords = str_replace(' ', '%20', $Keywords);
or
$Keywords = urlencode($Keywords);