WebClient failing on physical device and emulator - c#

UPDATE:
Maybe it's just me not understanding how oAuth works? I tried running
the query manually on http://www.apikitchen.com and I get a 400 error
there too! Just to be sure, am I constructing the URL correctly here?
POST URL:
https://api.bufferapp.com/1/oauth2/token.json?client_id=[hidden]&client_secret=[hidden]&redirect_uri=http://apps.joel-murphy.com/buffer/code/success.php&code=[the
access code I get from buffer starting with
1/]&grant_type=authorization_code
Original post:
I'm building a Windows Phone application which requires the use of data from a website. The website uses oAuth to authenticate users.
I used the built in web browser control to make a GET request to authenticate users. The official documentation requires the URL structure to be like this:
GET https://bufferapp.com/oauth2/authorize?
client_id=...&
redirect_uri=...&
response_type=code
This part of my app works. Although when it comes to exchanging the Authorization token for an access token from the server, I am facing problems. The official documentation requires the URL structure to be like this:
POST https://api.bufferapp.com/1/oauth2/token.json?
client_id=...&
client_secret=...&
redirect_uri=...&
code=...&
grant_type=authorization_code
Correct me if I'm wrong, but from what I know there is no way to make a POST request from a browser, unless submitting a form. For this reason, I have decided to use the WebClient class to submit data to the server. However, no matter if I run my code on an actual device or on the Visual studio emulator I always receive the following error:
The remote server returned an error: NotFound
Does anyone have any idea what's wrong with the following code? I've spent over 5 hours across 2 days trying to solve this error, but nothing seems to be working.
The code I'm using:
WebClient wc = new WebClient();
wc.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
wc.UploadStringAsync(new Uri(access_token_url), "POST", GetPostParameters());
void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
MessageBox.Show(e.Result);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
string GetPostParameters()
{
string data = "";
data += "client_id="+client_id + "&";
data += "client_secret=" +client_secret + "&";
data += "redirect_uri=" + redirect_uri+ "&";
data += "code=" + App.AccessToken + "&";
data += "grant_type=authorization_code";
return data;
}
Does anyone have any idea what's wrong? this is driving me crazy and it's a real shame that oauth has to be so complicated when it's such a used technology nowadays.
Thanks in advance.

Can you try URL-encoding the redirect_uri variable?

Related

Is there a way to retrieve the String the way it is actually uploaded to the server (as a whole)?

I am currently working on a OAuth2 implementation. However I am stuck on an Error 401. It seems like there is something wrong with my post request that is supposed to retrieve the access token from the Company the User logged in to. This is my code:
internal void RequestAccessToken(string code)
{
string requestBody = "grant_type="+ WebUtility.UrlEncode(GRANTTYPE)+ "&code=" + WebUtility.UrlEncode(code)+"&redirect_uri="+ WebUtility.UrlEncode(REDIRECT_URI);
WebClient client = new WebClient();
client.Headers.Add("Authorization",HeaderBase64Encode(CLIENT_ID, SECRETKEY));
var response = client.UploadString("https://thewebsiteiamcallingto.com/some/api", requestBody);
var responseString = client.OpenRead("https://thewebsiteiamcallingto.com/some/api");
}
My Questions are:
Is there anything wrong with the way I try to make the POST request ?
Is there a way to retrieve the whole string that is posted to the URI using UploadString?
P.S. I have seen this post regarding the POST creation. However I find the async part to be too complicated for my case.
Since we dont know the api documentation, I would suggest you to make a postman request and view the actual request sent and response received, and secondly make a request using your method and capture using a utility like wireshark and compare the difference.

I need an api that can upload some data to the web

I have an application made with c# which gets something from the user.
I need that piece of information to be submitted to me somehow by that application downloading a string,
for example, I have seen URL shortener APIs that would take a request, then shorten something, and that target URL would appear in my account.
I was thinking something along the lines of:
private void example_click(object sender, EventArgs e)`
{
WebClient wc1 = new WebClient();
string datatosend = "example"
string received = wc1.DownloadString("https://examplesite.com/api?=" + datatosend + "&format=json");
}
Or something along those lines, I used the main format of the shrinkearn API https://shrinkearn.com/, however, I think that there might be a site with their own API that works in this way.
Reference: DownloadString
Thanks in advance
Martin

Invalid PUT method from Webforms to Web API 2 (Azure)

I have a Web API in my Azure server and I'm making calls from an ASP.NET Webforms website.
I seem to be able to perform GET with no trouble. Now for the PUT, it's giving me this error:
The page you are looking for cannot be displayed because an invalid
method (HTTP verb) is being used
I was not able to DELETE either. I see some other topics where people disable some WebDav and stuff on their IIS servers and it works. But on Azure?
Below my code for the PUT:
HttpResponseMessage response = client.GetAsync("api/People/" + id).Result;
if (response.IsSuccessStatusCode)
{
var yourcustomobjects = response.Content.ReadAsAsync<People>().Result;
Uri peopleUrl = response.Headers.Location;
yourcustomobjects.name= "Bob";
response = await client.PutAsJsonAsync(peopleUrl, yourcustomobjects);
tbDebug.Text += await response.Content.ReadAsStringAsync();
}
Alright I grew tired of trying to fix this issue by enabling PUT.
So what I did, was I wrote a GET that makes the needed change in the database.
Cheers

Exception using WebClient calling HTTPS URLs

For about 3 months I have a public app which is using the WebClient to call some HTTPS API.
Until about 3 weeks ago everything worked fine, but suddenly the app stopped working and all the WebClient calls throw "The remote server returned an error: NotFound." exception.
I didn't update my app in any way, the API didn't change, I didn't notice any update for the Windows Phone.
I mention that my app is targeting the Windows Phone OS 7.1 and I also tried to use the HttpWebRequest class - the result is the same.
My code looks something like this:
private void tile_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(new Uri("https://www.google.com"));
}
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try {
StreamReader s = new StreamReader(e.Result);
string r = s.ReadToEnd();
MessageBox.Show(r);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This code will fail every time it's called with the above mentioned exception. If I would try to get the "http://www.google.com" or any other HTTP URL the code will work fine.
However, I need to use HTTPS as I need to send also credentials with the WebClient calls.
I found on the Internet that other people ran into such issues last year, but this problem was supposed to be fixed with Mango update.
Does anybody know how can I fix this issue or any workaround as I ran out of ideas.
Thank you in advance!
Regards,
Andrei
First the NotFound error is a generic one, to get the specifics of the problem you need to use a tool like Fiddler (with the emulator: http://blogs.msdn.com/b/fiddler/archive/2010/10/15/fiddler-and-the-windows-phone-emulator.aspx / with a device : http://blogs.msdn.com/b/fiddler/archive/2011/01/09/debugging-windows-phone-7-device-traffic-with-fiddler.aspx)
Now maybe it's a problem with the SSL certificate? I you visit the same URL with a desktop browser do you get a warning/error about its validity? If so you are out of luck, because I don't think you can override the validation of the certificate on Windows Phone like it's possible with the fwk on desktop.
But first try to debug with Fiddler to get some details.

Failing to retrieve access token in .NET desktop app

I'm writing a .NET app that runs on a Windows computer. It is not accessible through the browser. The problem is, I can't authenticate like I should. I'm currently coding in C# .NET, more specific in C#.
I have a webbrowser control on my form.
The user logs on to facebook through this webbrowser control.
After the logon, I start the authentication procedure.
I then retreive a code.
Here's where it goes wrong. With this code I want to obtain an access token.
The generated request URL looks like: https://graph.facebook.com/oauth/access_token?client_id=____MY_APP_ID______&redirect_uri=http://localhost/&client_secret=_____MY_APP_SECRET_____&code=____MY_RETREIVED_CODE_____ and is made through the code below.
Please note that my redirect URL is http://localhost. This should be okay, right?
Also, in my App Settings, I have the following information.
Site URL: http://localhost/
Site Domain: localhost
private String ExchangeCodeForToken(String code, Uri redirectUrl)
{
var TokenEndpoint = new Uri("https://graph.facebook.com/oauth/access_token");
var url = TokenEndpoint + "?" +
"client_id=" + _AppID + "&" +
"redirect_uri=" + redirectUrl + "&" +
"client_secret=" + _AppSecret + "&" +
"code=" + code;
var request = WebRequest.CreateDefault(new Uri(url));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (var responseReader = new StreamReader(responseStream))
{
var responseText = responseReader.ReadToEnd();
var token = responseText.Replace("access_token=", "");
return token;
}
}
}
}
When I execute this, I get this error:
error http://www.imageupload.org/getfile.php?id=50131&a=447f6fcc0ebd4d3f8e8a59a3a6e36ac3&t=4de0841c&o=0889D68FDC35508BA2C6F2689FCBAB7C30A8670CC9647EE598701D8BEC13ED278F0989D393&n=autherror.png&i=1
Webexception was unhandled by user code
The remote server returned an error: (400) Bad Request.
Here's where I think I might be going wrong:
Are my app settings correct?
Should my redirect url be http://localhost, even if there isn't actually a service listening there?
Most importantly:
how do I get rid of this error and retreive the access token?
Thanks in advance!
You get this error because you are not supposed to call this URL from a Desktop app : as far as I know, you can not use the token endpoint for Desktop app authentication. Also, you can get the access token directly (no need to ask for a code first). Here is what you have to do.
Load the following URL in your embedded web browser :
https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID&
redirect_uri=https://www.facebook.com/connect/login_success.html
The user will be asked to log in and will be redirected to this URL with the access token in the URL :
https://www.facebook.com/connect/login_success.html#access_token=...
So you have to detect the redirect and retrieve the access token from the URL.
Thanks quinten!
However, I've managed to solve my own problem by using the C# Facebook SDK.
This software development kit has been a really great help!
There are a lot of samples included (including authorisation)
Anyone who programs in .NET with facebook should check it out! Coding for facebook is now much easier.
http://facebooksdk.codeplex.com/

Categories