Making HTTP Post with authorization in C# - c#

I'm trying to Make your first call Paypal where the post message are in curl. I want to convert them to C#. But I can't edit Accept header.
curl https://api.sandbox.paypal.com/v1/oauth2/token \
-H "Accept: application/json" \
-H "Accept-Language: en_US" \
-u "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp:EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp" \
-d "grant_type=client_credentials"
My code is
string url = "https://api.sandbox.paypal.com/v1/oauth2/token";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//request.ContentType = "Content-type: text/xml";
//Client.Headers.Add(HttpRequestHeader.UserAgent, "user agent to send");
//request.Headers.Add(HttpRequestHeader.Accept, "application/json");
//request.Headers.Add(HttpRequestHeader.Referer, "string");
//request.Headers.Add(HttpRequestHeader.AcceptLanguage, "string");
request.Method = "POST";
string authInfo = "AfKNLhCngYfGb-Eyv5gn0MnzCDBHD7T9OD7PATaJWQzP3I1xDRV1mMK1i3WO:ECSAgxAiBE00pq-SY9YB5tHw0fd2UlayHGfMr5fjAaULMD2NFP1syLY7GCzt";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
//request.Headers["Accept"] = "application/json";
request.Headers["Accept-Language"] = "en_US";
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("grant_type=client_credentials");
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
I'm getting internal server error 500. But it works fine with curl. How can I do this in C#?

One method I have used before to supply named values like this is to use the UploadValues method of a WebClient. This perfectly replicates the functionality you find in curl (I have used this for integration with the Instagram API for the same purpose).
Here is a little sample code to illustrate:
string authInfo = "AfKNLhCngYfGb-Eyv5gn0MnzCDBHD7T9OD7PATaJWQzP3I1xDRV1mMK1i3WO:ECSAgxAiBE00pq-SY9YB5tHw0fd2UlayHGfMr5fjAaULMD2NFP1syLY7GCzt";
WebClient client = new WebClient();
NameValueCollection values;
values = new NameValueCollection();
values.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo)));
values.Add("Accept", "application/json");
values.Add("Accept-Language", "en_US");
client.UploadValues("https://api.sandbox.paypal.com/v1/oauth2/token", values);
This may not work out of the box (as I have laid it out above) but will hopefully take you in the right direction.

Related

Converting CURL request to C# for accessing Snipcart API returns 401 Unauthorized

I am trying to access the Snipcart API (Reference - https://docs.snipcart.com/api-reference/authentication). I have created an API key and followed the steps mentioned in the documentation.
I am trying to Convert a CURL request to C#. I chose to use HttpWebRequest. I get 401 Unauthorized returned from the Server. I am not able to figure out what's wrong with my request.
Actual Curl Request: - curl -H "Accept: application/json"
https://app.snipcart.com/api/orders
-u {API_KEY}:
The following is the code that i tried converting the above curl request to
string baseURL = "https://app.snipcart.com/api/orders";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseURL);
req.AllowAutoRedirect = true;
req.ContentType = "application/json";
req.Accept = "application/json";
req.Method = "GET";
req.Headers.Add("API_Key", "MY_API_KEY_VALUE_COMES_HERE");
string jsonResponse = null;
using (WebResponse resp = req.GetResponse())
{
if (req.HaveResponse && resp != null)
{
using (var reader = new StreamReader(resp.GetResponseStream()))
{
jsonResponse = reader.ReadToEnd();
}
}
}
Console.Write(jsonResponse);
You need to send the header as a basic auth header instead of "API_Key" Try something like this.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseURL);
req.AllowAutoRedirect = true;
req.ContentType = "application/json";
req.Accept = "application/json";
req.Method = "GET";
var basicAuthHeader = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("MY_API_KEY_VALUE_COMES_HERE"));
req.Headers.Add("Authorization", "Basic " + basicAuthHeader);
The API reference from Snipcart says you need Basic HTTP Authentication.
When I have a look at your code, I think you should change this line
req.Headers.Add("API_Key", "MY_API_KEY_VALUE_COMES_HERE");
to
req.Credentials = new NetworkCredential("API_Key", "MY_API_KEY_VALUE_COMES_HERE");
A kind of the same issue is described in this topic, you can take it as reference.
If it's not solving the issue, you could have a closer look at the curl API parameters manual, and then translate it to C# code.
curl -H "Accept: application/json" \
https://app.snipcart.com/api/orders \
-u {API_KEY}:

How to set Twitch TV channel title

I am working on being able to have my custom chat bot to update my primary channel's title (status). I am following this post and I am trying to get the access_token from the REDIRECT_URI.
The URI that contains the redirect is:
https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=channel_editor
I have manually tested this with my CLIENT_ID and REDIRECT_URI set to http://localhost and I get this response from the above URI (which is what I want):
http://localhost/#access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&scope=channel_editor
I am trying to get the access_token from this URI, but I cant seem to get to it from the code below. My response is:
https://api.twitch.tv/kraken/oauth2/authenticate?action=authorize&client_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&redirect_uri=http%3A%2F%2Flocalhost&response_type=token&scope=channel_editor
Code:
string clientID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string redirectURL = "http://localhost";
string url = string.Format("https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id={0}&redirect_uri={1}&scope=channel_editor",
clientID, redirectURL);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = false;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string redirUrl = response.Headers["Location"];
response.Close();
// Show the redirected url
Console.WriteLine("You're being redirected to: " + redirUrl);
This is a console application
This is not directly related to c# but implementing it should be easy enough https://discuss.dev.twitch.tv/t/how-to-set-title/390/2
This twitch dev post helped me out until I got to the "Make the request" step. My problem was I needed to make the C# equivalent of this cURL command to change the channel's title:
curl -H 'Accept: application/vnd.twitchtv.v2+json'
-H 'Authorization: OAuth <access_token>'
-d "channel[status]=New+Status!&channel[game]=New+Game!"
-X PUT https://api.twitch.tv/kraken/channels/CHANNEL
Solution:
I decided to manually get the access_token from the authentication request by ctrl + c and ctrl + v the token from the URI given below and store it into my database:
http://localhost/#access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&scope=channel_editor
Then, I used Postman to generate my RestSharp code with the body request in JSON:
string accessToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var client = new RestClient("https://api.twitch.tv/kraken/channels/CHANNEL_NAME");
var request = new RestRequest(Method.PUT);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "OAuth " + accessToken);
request.AddHeader("accept", "application/vnd.twitchtv.v3+json");
request.AddParameter("application/json", "{\"channel\":{\"status\":\"Hello World\"}}",
ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

How to send POST request in Xamarin?

I've built my backend in rails.
My email address is "sample#zmail.com" and it's already registered. The password is "28902890" here
After giving the following command in terminal
curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST https://auth-agdit.herokuapp.com/api/v1/sessions -d "{\"user\":{\"email\":\"sample#zmail\",\"password\":\"28902890\"}}"
I get this response from my backend,
{"success":true,"info":"Logged in :) ","data":{"authentication_token":"iexGFwJ6HwERQZ3wJ4NG"}}
Now I need to get this data from my Android app.
I can get json by using WebClient().downloadString() method for simple json where authentication is not needed and the request method is GET.
Now I need to get the output Json for POST method.
How can I accomplish that?
There are several methods of doing this. You could use the Xamarin component called RestSharp. This will provide you with easy methods of interfacing with your backend.
var request = new RestRequest("resource/{id}", Method.POST);
request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method
request.AddUrlSegment("id", 123); // replaces matching token in request.Resource
// add parameters for all properties on an object
request.AddObject(object);
// execute the request
RestResponse response = client.Execute(request);
If you do want to simply use the WebClient class provided by the BCL you can use the WebClient.UploadString(string, string) method like so:
using (WebClient client = new WebClient())
{
string json = "{\"user\":{\"email\":\"sample#zmail\",\"password\":\"28902890\"}}";
client.UploadString("https://example.com/api/v1/sessions, json);
}
If you need more control over the request (such as setting accept headers, etc.) then you can use HttpRequest, see this question for an example of that.
This is how I did it:
WebClient wc = new WebClient();
string baseSiteString = wc.DownloadString("https://auth-agdit.herokuapp.com");
string csrfToken = Regex.Match(baseSiteString, "<meta name=\"csrf-token\" content=\"(.*?)\" />").Groups[1].Value;
string cookie = wc.ResponseHeaders[HttpResponseHeader.SetCookie];
Console.WriteLine("CSRF Token: {0}", csrfToken);
Console.WriteLine("Cookie: {0}", cookie);
wc.Headers.Add(HttpRequestHeader.Cookie, cookie);
wc.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
wc.Headers.Add(HttpRequestHeader.Accept, "application/json, text/javascript, */*; q=0.01");
wc.Headers.Add("X-CSRF-Token", csrfToken);
wc.Headers.Add("X-Requested-With", "XMLHttpRequest");
string dataString = #"{""user"":{""email"":""email_here"",""password"":""password_here""}}";
// string dataString = #"{""user"":{""email"":"""+uEmail+#""",""password"":"""+uPassword+#"""}}";
byte[] dataBytes = Encoding.UTF8.GetBytes(dataString);
byte[] responseBytes = wc.UploadData(new Uri("https://auth-agdit.herokuapp.com/api/v1/sessions.json"), "POST", dataBytes);
string responseString = Encoding.UTF8.GetString(responseBytes);
Console.WriteLine(responseString);
Try with this code:
Uri address = new Uri("http://example.com/insert.php");
NameValueCollection nameValueCollection = new NameValueCollection();
nameValueCollection["Name"] = "string-input";
var webClient = new WebClient();
webClient.UploadValuesAsync(address, "POST", nameValueCollection);

Connecting to Urban Airship REST API with c#

I am getting a 400 bad request error when trying to connect to the Urban Airship Rest API. Below is the curl command I am trying to replicate in .NET. The .NET code is at the end. Please help.
curl -v -X POST
-u "username:passowrd"
-H "Content-type: application/json"
-H "Accept: application/vnd.urbanairship+json; version=3;"
--data '{"audience" : {"tag":"1_13_98"},
"device_types" : "all",
"notification" : {"alert": "Tag push alert"}
}'
https://go.urbanairship.com/api/push
The c# code I am trying to use is:
var json = gcm.ToJsonString();
Console.WriteLine("JSON GCM Message: " + json);
var uri = new Uri("https://go.urbanairship.com/api/push/?");
var encoding = new UTF8Encoding();
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.Credentials = new NetworkCredential(username, master);
request.ContentType = "application/json";
WebHeaderCollection myWebHeaderCollection = request.Headers;
myWebHeaderCollection.Add(HttpRequestHeader.Accept, "application/vnd.urbanairship+json; version=3;");
request.ContentLength = encoding.GetByteCount(json);
using (var stream = request.GetRequestStream())
{
stream.Write(encoding.GetBytes(json), 0, encoding.GetByteCount(json));
stream.Close();
var response = request.GetResponse();
response.Close();
}
return true;
The API for urbanAirship can be found here:
http://docs.urbanairship.com/reference/api/v3/push.html
And here is an example request..
POST /api/push HTTP/1.1
Authorization: Basic <master authorization string>
Content-Type: application/json
Accept: application/vnd.urbanairship+json; version=3;
{
"audience" : {
"device_token" : "998BAD77A8347EFE7920F5367A4811C4385D526AE42C598A629A73B94EEDBAC8"
},
"notification" : {
"alert" : "Hello!"
},
"device_types" : "all"
}
I've created a c# .Net library for talking to Urban Airship API V3
You can find it here:
https://github.com/JeffGos/urbanairsharp
Hope it helps
Instead of using the header collection (which is throwing an exception) try setting the Accept property on the Request object, e.g. request.Accept = "application/vnd.urbanairship+json; version=3;"
If you still get a 400, try looking in the response body for more details.

ASP.NET Equivalent to this cURL command

I'm working with the Twilio API and it provides examples in PHP and Ruby. I'm working on a site to send text messages through the API that's coded in ASP.NET MVC 3, and using my limited knowledge of the WebRequest object, I was able to translate this:
curl -X POST 'https://api.twilio.com/2010-04-01/Accounts/AC4840da0d7************f98b20b084/SMS/Messages.xml' \
-d 'From=%2B14155992671' \
-u AC4840da0d7************f98b20b084:f7fc2**************75342
Into this:
var request =
WebRequest.Create(MessageApiString + "?From=+14*********1&To=" + Phone + "&Body=" + smsCampaign.Message);
var user = "AC4840da0d7************f98b20b084";
var pass = "f7fc2**************75342";
string credentials = String.Format("{0}:{1}", user, pass);
request.Headers.Add("Authorization", credentials);
var result = request.GetResponse();
But it's not authenticating, I'm getting a 401 from their API. What is the equivalent C# to the cURL -u command?
Update
var request =
WebRequest.Create(MessageApiString + "?From=+14155992671&To=" + Phone + "&Body=" + smsCampaign.Message);
var cc = new CredentialCache();
cc.Add(new Uri(MessageApiString), "NTLM", new NetworkCredential("AC4840da0d7************f98b20b084", "f7fc2**************75342"));
request.Credentials = cc;
request.Method = "POST";
var result = request.GetResponse();
Still getting 401. Any ideas?
Update 2
Alright, thanks to the answers below I was able to get through to the api, but now I'm getting a 400 Bad Request. Is there a cleaner way to build a query string to pass this data along? The three fields are From, To, and Body.
Try including
request.Method = "POST";
and
request.Credentials = new NetworkCredential("username", "password");
The -u option in Curl is to specify a username and password for Server Authentication.
For C# this is set using the WebRequest.Credentials property.

Categories