c# WebRequest to Google API Bad Request - c#

When I run this code to call the Google API, all I get is a 'Bad Request' error, but I don't know where I'm going wrong.
The code is being returned no problem from the authorization page on Google, it's when the code gets to the part below that it fails. Please could someone tell me where I'm going wrong here?
I'm aware that there are libraries for this, but I'm trying to understand how to do this the RESTful way as a learning exercise.
Thanks
var code = Request.QueryString["code"];
var accessToken = string.Empty;
var req0 = WebRequest.Create("https://accounts.google.com/o/oauth2/token");
req0.Method = "POST";
string postData = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri= {3}&grant_type=authorization_code",
code, //the code i got back
"xxxx.apps.googleusercontent.com",
"xxx",
Url.Encode("http://localhost/home/callback")
); //my return URI
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
req0.ContentType = "application/x-www-form-urlencoded";
req0.ContentLength = byteArray.Length;
using (Stream dataStream = req0.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
}
try
{
using (WebResponse response = req0.GetResponse())
{
using (var dataStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
{
string responseFromServer = reader.ReadToEnd();
var ser = new JavaScriptSerializer();
accessToken = ser.DeserializeObject(responseFromServer).ToString();
}
}
}
}
catch (WebException wex)
{
Debug.WriteLine(wex.ToString());
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}

The Google API is very finicky when it comes to what you have entered into the API Console for your client id return URI, and what you enter in your code to call it.
I was missing the trailing forward slash. That was all. Lesson learnt...
Thanks to Jon and Sandeep for help point me in the right direction by comparing what was in the network traffic, and what I should have been sending.

Related

C# API GetResponse issue

I'm quite new to c# and I'm having an issue when trying to call an API to post some CSV data using the following code:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://myurl");
request.Method = "POST";
request.Headers.Add("X-Api-Key:" + apiKey);
request.Headers.Add("X-Api-Secret:" + apiSecret);
request.ContentType = "text/csv";
using (StreamWriter swCSVData = new StreamWriter(request.GetRequestStream()))
{
StreamReader csvReader = new StreamReader(File.OpenRead("C:\\Test\\conf-ato-sprmbrinfo-batch-001.csv"));
while (!csvReader.EndOfStream)
{
swCSVData.WriteLine(csvReader.ReadLine());
}
csvReader.Close();
}
HttpWebResponse response = null;
try
{
Console.WriteLine("Attempting response....");
response = (HttpWebResponse)request.GetResponse();
Console.WriteLine("Got response....");
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
strResponseValue = reader.ReadToEnd();
}
}
}
Console.WriteLine(strResponseValue);
File.WriteAllText("C:\\Test\\apioutput.txt",strResponseValue);
}
catch ( Exception ex)
{
strResponseValue = "{\"errorMessages\":[\"" + ex.Message.ToString() + "\"],\"errors\":{}}";
}
If I run this code using the post test at ptsv2.com, then I can see that the api call looks like I would expect and I get a response. However, when I change my code to point to my required URL it seems to just hang on the following line:
response = (HttpWebResponse)request.GetResponse();
Does anyone have any idea as to why this could be happening?
Also happy for any recommendations to make my code better.
Thanks in advance.
It turns out this was a security issue once I could see the exception being returned. I had to add the following line of code for my request:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Thanks to the people who took the time to comment on my original question.

Check if API url is valid - POST call

I need to allow user to enter a remote API url with basic authentication/ or a static token to POST the data from my application to the URL at specified intervals.
I tried setting the "HEAD" only but it does the GET operation and throws 405 - Method Not Allowed error for all the requests.
I would like to know if there is any way to validate the url and the credentials with given POST url.
I understand I can valid the the url but my concern is to ensure that I need to validate the basic auth credentials entered by the user is also correct.
Try this-
try
{
WebRequest tRequest = WebRequest.Create("YOUR API URL");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
//REQUIERED PARAMETERIZED DATA
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", ApplicationID));
tRequest.Headers.Add(string.Format("YOUR HEADER"));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
str = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
str = ex.Message;
}

GetResponse() Error in the PayPal functionality when trying to checkout

So I'm following the WingTip Toy tutorial, and I know its sort of old but it was error free until I got to the point where I needed to checkout with PayPal using the sandbox developing tool
This is the code where the error occurs
//Retrieve the Response returned from the NVP API call to PayPal.
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
string result;
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
}
return result;
And this is the error im getting when i run it
[ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse.]
Please note I'm a beginner
Edit: The full code is here
public string HttpCall(string NvpRequest)
{
string url = pEndPointURL;
string strPost = NvpRequest + "&" + buildCredentialsNVPString();
strPost = strPost + "&BUTTONSOURCE=" + HttpUtility.UrlEncode(BNCode);
HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
objRequest.Timeout = Timeout;
objRequest.Method = "POST";
objRequest.ContentLength = strPost.Length;
try
{
using (StreamWriter myWriter = new StreamWriter(objRequest.GetRequestStream()))
{
myWriter.Write(strPost);
}
}
catch (Exception)
{
// No logging for this tutorial.
}
//Retrieve the Response returned from the NVP API call to PayPal.
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
string result;
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
}
return result;
}
objRequest.ContentLength = strPost.Length;
What are you trying to do here? The framework sets the content length automatically. The content length is in bytes but you have given the number of characters.
That's why the error complains: You have written a different number of characters than you said you would write.
Delete that line.
Your code would become a lot simpler if you used HttpClient. Should be about 5 lines.

HttpWebRequest get 404 page only when using POST mode

First of all: I know this has been asked over 100 times, but most of these questions were eigher caused by timeout problems, by incorrect Url or by foregetting to close a stream (and belive me, I tried ALL the samples and none of them worked).
So, now to my question: in my Windows Phone app I'm using the HttpWebRequest to POST some data to a php web service. That service should then save the data in some directories, but to simplify it, at the moment, it only echos "hello".
But when I use the following code, I always get a 404 complete with an apache 404 html document. Therefor I think I can exclude the possibility of a timeout. It seems like the request reaches the server, but for some reason, a 404 is returned. But what really makes me be surprised is, if I use a get request, everything works fine. So here is my code:
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp(server + "getfeaturedpicture.php?randomparameter="+ Environment.TickCount);
webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0";
webRequest.Method = "POST";
webRequest.ContentType = "text/plain; charset=utf-8";
StreamWriter writer = new StreamWriter(await Task.Factory.FromAsync<Stream>(webRequest.BeginGetRequestStream, webRequest.EndGetRequestStream, null));
writer.Write(Encoding.UTF8.GetBytes("filter=" + Uri.EscapeDataString(filterML)));
writer.Close();
webRequest.BeginGetResponse(new AsyncCallback((res) =>
{
string strg = getResponseString(res);
Stator.mainPage.Dispatcher.BeginInvoke(() => { MessageBox.Show(strg); });
}), webRequest);
Although I don't think this is the reason, here's the source of getResponseString:
public static string getResponseString(IAsyncResult asyncResult)
{
HttpWebRequest webRequest = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse webResponse;
try
{
webResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult);
}
catch (WebException ex)
{
webResponse = ex.Response as HttpWebResponse;
}
MemoryStream tempStream = new MemoryStream();
webResponse.GetResponseStream().CopyTo(tempStream);
tempStream.Position = 0;
webResponse.Close();
return new StreamReader(tempStream).ReadToEnd();
}
This is tested code work fine in Post method with some body. May this gives you an idea.
public void testSend()
{
try
{
string url = "abc.com";
string str = "test";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "text/plain; charset=utf-8";
req.BeginGetRequestStream(SendRequest, req);
}
catch (WebException)
{
}
}
//Get Response and write body
private void SendRequest(IAsyncResult asyncResult)
{
string str = "test";
string Data = "data=" + str;
HttpWebRequest req= (HttpWebRequest)asyncResult.AsyncState;
byte[] postBytes = Encoding.UTF8.GetBytes(Data);
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = postBytes.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
request.BeginGetResponse(SendResponse, req);
}
//Get Response string
private void SendResponse(IAsyncResult asyncResult)
{
try
{
MemoryStream ms;
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
HttpWebResponse httpResponse = (HttpWebResponse)response;
string _responestring = string.Empty;
using (Stream data = response.GetResponseStream())
using (var reader = new StreamReader(data))
{
_responestring = reader.ReadToEnd();
}
}
catch (WebException)
{
}
}
I would suggest you to use RestSharp for your POST requests in windows phone. I am making an app for a startup and i faced lots of problems while using a similar code as yours. heres an example of a post request using RestSharp. You see, instead of using 3 functions it can be done in a more concise form. Also the response can be handled efficiently. You can get RestSharp from Nuget.
RestRequest request = new RestRequest("your url", Method.POST);
request.AddParameter("key", value);
RestClient restClient = new RestClient();
restClient.ExecuteAsync(request, (response) =>
{
if (response.StatusCode == HttpStatusCode.OK)
{
StoryBoard2.Begin();
string result = response.Content;
if (result.Equals("success"))
message.Text = "Review submitted successfully!";
else
message.Text = "Review could not be submitted.";
indicator.IsRunning = false;
}
else
{
StoryBoard2.Begin();
message.Text = "Review could not be submitted.";
}
});
It turned out the problem was on the server-side: it tried it on the server of a friend and it worked fine, there. I'll contact the support of the hoster and provide details as soon as I get a response.

Error getting response stream (ReadDone2): Receive Failure

Help me please.
After sending post query i have webexception "Error getting response stream (ReadDone2): Receive Failure". help get rid of this error. thanks.
piece of code
try
{
string queryContent = string.Format("login={0}&password={1}&mobileDeviceType={2}/",
login, sessionPassword, deviceType);
request = ConnectionHelper.GetHttpWebRequest(loginPageAddress, queryContent);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())//after this line //occurs exception - "Error getting response stream (ReadDone2): Receive Failure"
{
ConnectionHelper.ParseSessionsIdFromCookie(response);
string location = response.Headers["Location"];
if (!string.IsNullOrEmpty(location))
{
string responseUri = Utils.GetUriWithoutQuery(response.ResponseUri.ToString());
string locationUri = Utils.CombineUri(responseUri, location);
result = this.DownloadXml(locationUri);
}
response.Close();
}
}
catch (Exception e)
{
errorCout++;
errorText = e.Message;
}
//Methot GetHttpWebRequest
public static HttpWebRequest GetHttpWebRequest(string uri, string queryContent)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Proxy = new WebProxy(uri);
request.UserAgent = Consts.userAgent;
request.AutomaticDecompression = DecompressionMethods.GZip;
request.AllowWriteStreamBuffering = true;
request.AllowAutoRedirect = false;
string sessionsId = GetSessionsIdForCookie(uri);
if (!string.IsNullOrEmpty(sessionsId))
request.Headers.Add(Consts.headerCookieName, sessionsId);
if (queryContent != string.Empty)
{
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
byte[] SomeBytes = Encoding.UTF8.GetBytes(queryContent);
request.ContentLength = SomeBytes.Length;
using (Stream newStream = request.GetRequestStream())
{
newStream.Write(SomeBytes, 0, SomeBytes.Length);
}
}
else
{
request.Method = "GET";
}
return request;
}
using (Stream newStream = request.GetRequestStream())
{
newStream.Write(SomeBytes, 0, SomeBytes.Length);
//try to add
newStream.Close();
}
In my case the server did not send a response body. After fixing the server, the "Receive Failure" vanished.
So you have two options:
Don't request a response stream, if you can live without it.
Make sure the server sends a response body.
E.g., instead of
self.send_response(200)
self.wfile.close()
the Python server code should be
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write("Thanks!\n")
self.wfile.close()
its not Xamarin or .NET's bug. :wink:
your server side endpoint fails when requesting. :neutral:
check your API endpoint if you own the api or contact support if you are getting API from third party company or service.
why it happens randomly : :wink:
because bug is in your inner if or loop blocks and it happens when it goes through this buggy loop or if.
best regards. :smile:

Categories