Connecting to Urban Airship REST API with c# - 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.

Related

Why does cURL work, but my HttpWebRequest does not?

I'm trying to take the below curl statement and reperform it in a c# method. The following curl statement works fine (I masked the credentials and IP address) so I'm sure the destination server is willing to play ball:
curl -D- -u user:password -X POST --data #data.txt -H "Content-Type: application/json" http://0.0.0.0:8080/rest/api/2/issue/
where the data.txt looks like this:
{
"fields": {
"project":{"id": "10000"},
"summary": "No REST for the Wicked.",
"description": "Creating of an issue using ids for projects and issue types using the REST API",
"issuetype": {"id": "10002"},
"customfield_10115" : "3212.12",
"customfield_10116" : "Client Name",
"customfield_10117" : "Engagement Name",
"customfield_10118" : "TEst",
"customfield_10121" : "2019-11-30",
"customfield_10120" : "Daily"
}
}
However, when I try and re-perform the above in C#, it's giving me the dreaded I'm-Not-Telling-You-Why-This-Doesn't-Work message: "The remote server returned an error: (500) Internal Server Error."
Here's my C# Code.
Console.WriteLine("Start");
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://0.0.0.0:8080/rest/api/2/issue/");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization", "Basic user:password");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"fields\": {\"project\":{ \"id\": \"10000\"},\"summary\": \"No REST for the Wicked.\",\"description\": \"description text\",\"issuetype\": { \"id\": \"10002\"},\"customfield_10115\" : \"3212.12\",\"customfield_10116\" : \"Client Name\",\"customfield_10117\" : \"Engagement Name\",\"customfield_10118\" : \"Payroll\",\"customfield_10121\" : \"2019-11-30\",\"customfield_10120\" : \"Daily\"}}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Any ideas?
Kudos to fenixil who spotted my issue:
Just needed to Base64 the username/password pair. Works like a champ now!

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}:

AWS 400 Bad Request error C#

I am tasked with developing an application that Posts data to the client's Amazon Web Service api. The instructions from client were that I have to use the POST method for URL http://ec.*******.compute.amazonaws.com/api and gave me a token to use for authentication.
My C# code looks like this
SystemSettings _Settings = GetSystemSettings(); //URL and Token values
try
{
JObject jsonObject = GetJsonData();
WebRequest request = HttpWebRequest.Create(_Settings.HttpService);
if (!string.IsNullOrEmpty(_Settings.BearerToken))
{
request.PreAuthenticate = true;
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + _Settings.BearerToken);
}
//Uploading JSON
request.ContentType = "application/json; charset=utf-8";
//using Http POST Method
request.Method = "POST";
//Start uploading data
StreamWriter httpStream = new StreamWriter(request.GetRequestStream());
httpStream.Write(jsonObject.ToString());
httpStream.Close(); // Close stream
httpStream.Dispose(); //Dispose stream
//Check for response from the web server
WebResponse response = request.GetResponse(); //Error comes here
.
.
.
.
}
catch(Exception ex)
{
_log.Error("ERROR Uploading to stream(" + _Settings.HttpService + ")", ex);
}
The request ends up with a 400 Bad Request. Does this require working with Amazon SDK to connect to use the Bearer Token?
The customer has said the following:
Our API Authentication is RFC6750, Can you please make a request to
the API as follows:
POST /api/ HTTP/1.1
Host: ec.************.compute.amazonaws.com
Authorization: Bearer ***TOKEN***

getting access tokens forbidden 403 and some times 400 Bad Request

I am facing the following issue while issuing request to retrieve the access token. First, I registered the application in developer console and consequently downloaded the client secret file. The content of which is as below: (i have marked secrets as xxxxx).
{"installed":{"client_id":"xxxx","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"xxxx","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
In the developer documentation (located at : https://developers.google.com/identity/protocols/OAuth2InstalledApp ) however, it is given a different address to connect and retrieve the access tokens.
POST /oauth2/v3/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
I am confused
1. which URI's to use to get access to tokens.
2. What redirect_uri should be used? Is it the local host or the uri as noted in the developer documentation.
When i use the client secret token uri, i receive a 400 bad request and when i use the uri as noted in the developer documentation, I receive forbidden 403.
POST /oauth2/v3/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
Can someone kindly clarify. It would be an immense help.
I am writing a console application and i do not want to use the C# api already provided. The sample code is located below.
Where am I doing wrong?
string tokenUri = #"https://accounts.google.com/o/oauth2/token";
HttpWebRequest request=(HttpWebRequest) WebRequest.Create(tokenUri);
NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
outgoingQueryString.Add("code", this.clientCode);
outgoingQueryString.Add("client_id", this.clientID);
outgoingQueryString.Add("client_secret", this.clientSecret);
outgoingQueryString.Add("redirect_uri", "https://oauth2-login-demo.appspot.com/code");
outgoingQueryString.Add("grant_type","authorization_code");
string postdata = outgoingQueryString.ToString();
byte[] byteArray = Encoding.UTF8.GetBytes(postdata);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream reqStr = request.GetRequestStream();
reqStr.Write(byteArray, 0, byteArray.Length);
reqStr.Flush();
reqStr.Close();
HttpWebResponse response=request.GetResponse() as HttpWebResponse;
Console.WriteLine(response.StatusCode.ToString());
Found out that url-encoded is not to be used, instead json is expected. revised the code as below and still 400 persist.
string tokenUri = "https://accounts.google.com/o/oauth2/token";
TokenFileds f = new TokenFileds() { client_code = this.clientCode, client_id = this.clientID, client_secret = this.clientSecret, redirect_uri = "urn:ietf:wg:oauth:2.0:oob", grant_type = "authorization_code" };
//string retString=this.SerializeToJson<TokenFileds>(f);
string retString = this.NewjsonLib(f);
byte[] byteArray=Encoding.UTF8.GetBytes(retString);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tokenUri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
request.ContentLength = byteArray.Length;
Stream strm = request.GetRequestStream();
strm.Write(byteArray, 0, byteArray.Length);
strm.Flush();
strm.Close();
HttpWebResponse response =request.GetResponse() as HttpWebResponse;
you need to insure few things before as,
1. While creating the project you have to select other type project.
2. You must enable the drive API's.
3. Then make sure you are posting this url L"/o/oauth2/token" to this server L"accounts.google.com".
4. you are giving Content Type as L"Content-Type: application/x-www-form-urlencoded".
5.and your header should be like this,
wstring wstrHeader = L"code="+ m_wstrAuthCode +
L"&client_id=327293200239-4n4a8ej3jlm1fdufqu7httclg5a28m1a.apps.googleusercontent.com&client_secret=ieEGhWhPhotp0ZegdgRLkOxv&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code";
here you have to replace m_wstrAuthCode to your authentication code.
6.then you will get the Json from server as,
{
"access_token" : "ya29.7gGjEgvIVIMOO7bHegijk2KygAVjjxz7bCOxUvG7OKeKTc66Nom1e9zCqSyzR4V0bTYC",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/Vc9A7nfib4ikeYs0-TBfrs-isvjRDt-JI2ftj0pNVcRIgOrJDtdun6zK6XiATCKT"
}
7.you need to parse it to get the access token.

Making HTTP Post with authorization in 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.

Categories