So based on Tom Raz post Ionic push notification api in c# with WebApi. I tried to implement a method to send a push notification using the ionic push notifications api here is my code:
public void sendToIonic(string regId, string msg) {
using (var client = new HttpClient())
{
string data = "{ \"user_ids\":[\" "+ regId + "\"],\"notification\":{\"alert\":\" "+ msg + "\"}}";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
client.BaseAddress = new Uri("https://push.ionic.io/api/v1/push");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("X-Ionic-Application-Id", "1d74b1f2");
var keyBase64 = "Basic %s" + "53a03dc7d9ce58511263e40580294f62af36b89be7cc4db2";
client.DefaultRequestHeaders.Add("Authorization", keyBase64);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://push.ionic.io/api/v1/push");
request.Content = new StringContent(data, Encoding.UTF8, "application/json");
var response = client.SendAsync(request).Result;
}
}
But I keep getting the response error 403 Forbidden;. This is the complete response:
{StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Date: Fri, 15 Jan 2016 20:50:33 GMT
ETag: W/"35-nGlZv/eC8CyS+KJzQ1P9rg"
Server: Cowboy
Via: 1.1 vegur
X-Powered-By: Express
Content-Length: 53
Content-Type: application/json; charset=utf-8
}}
Not sure what is wrong. I am stuck. Any help would be appreciated.
var keyBase64 = "Basic %s" + "..."
%s this is to concatenate in python.
You need to convert to Base64
You can use
client.DefaultRequestHeaders.Add("X-Ionic-Application-Id", "1d74b1f2");
var IONIC_PRIVATE_KEY_BASE_64 = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("53a03dc7d9ce58511263e40580294f62af36b89be7cc4db2:")); // ends with two points
var keyBase64 = "Basic " + IONIC_PRIVATE_KEY_BASE_64 ;
client.DefaultRequestHeaders.Add("Authorization", keyBase64);
http://docs.ionic.io/docs/push-sending-push#section-authenticating-your-requests
Related
I have sample code written in C# in Visual Studio on Windows 10 that attempts to send a POST request with custom headers to a service running at http://localhost:9998 which is failing.
When I look at the request the Content-Type header field is being sent as ContentType (no hyphen).
httpRequestMessage:Method: POST, RequestUri: 'http://localhost:9998/',
Version: 1.1, Content: System.Net.Http.ByteArrayContent, Headers: {
ContentType: application/vnd.com.documents4j.any-msword Accept:
application/pdf Converter-Job-Priority: 1000 }response:StatusCode:
500, ReasonPhrase: 'Request failed.', Version: 1.1, Content:
System.Net.Http.StreamContent, Headers: { Connection: close Date:
Sat, 10 Apr 2021 22:39:24 GMT Content-Length: 1031 Content-Type:
text/html; charset=ISO-8859-1 }Press any key to continue . . .
I am wondering if this is the cause of the problem?
I have code written in C# that uses RestSharp and that sends Content-Type correctly and returns a successful result.
I have code written in Java that also sends Content-Type correctly and returns a successful result.
Sample Code 1 [Problem sending Content-Type as ContentType]
using System;
using System.Net;
using System.IO;
using System.Net.Http;
namespace HttpPOST10
{
class Program
{
public static string MyUri { get; private set; }
static void Main(string[] args)
{
// string url = "http://localhost:9998";
string url = "http://localhost:8888"; // Fiddler
Uri myUri = new Uri(url);
string srcFilename = #"C:\temp2\Sample.doc";
string destFileName = #"C:\temp3\Sample-HttpPOST10.pdf";
UploadFile(url, srcFilename, destFileName);
}
private static bool UploadFile(string url, string srcFilename, string destFileName)
{
HttpClient httpClient = new HttpClient();
byte[] data;
data = File.ReadAllBytes(srcFilename);
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(url),
Headers = {
{ HttpRequestHeader.ContentType.ToString(), "application/vnd.com.documents4j.any-msword" },
{ HttpRequestHeader.Accept.ToString(), "application/pdf" },
{ "Converter-Job-Priority", "1000" },
// {"User-Agent", "RestSharp/106.11.8.0" }
},
Content = new ByteArrayContent(data)
};
Console.Write("httpRequestMessage:" + httpRequestMessage);
var response = httpClient.SendAsync(httpRequestMessage).Result;
Console.Write("response:" + response);
return true;
}
}
}
Thank you Jimi - have now got a successful response.
httpRequestMessage:Method: POST, RequestUri: 'http://localhost:9998/',
Version: 1.1, Content: System.Net.Http.ByteArrayContent, Headers: {
ContentType: application/vnd.com.documents4j.any-msword Accept:
application/pdf Converter-Job-Priority: 1000 Content-Type:
application/vnd.com.documents4j.any-msword }response:StatusCode: 200,
ReasonPhrase: 'OK', Version: 1.1, Content:
System.Net.Http.StreamContent, Headers: { Vary: Accept-Encoding
Transfer-Encoding: chunked Date: Mon, 12 Apr 2021 03:04:14 GMT
Content-Type: application/pdf
The code change was:
private static bool UploadFile(string url, string srcFilename, string destFileName)
{
HttpClient httpClient = new HttpClient();
byte[] data;
data = File.ReadAllBytes(srcFilename);
HttpContent content = new ByteArrayContent(data);
content.Headers.Add("Content-Type", "application/vnd.com.documents4j.any-msword");
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(url),
Headers = {
{ HttpRequestHeader.ContentType.ToString(), "application/vnd.com.documents4j.any-msword" },
{ HttpRequestHeader.Accept.ToString(), "application/pdf" },
{ "Converter-Job-Priority", "1000" },
},
Content = content
};
Console.Write("httpRequestMessage:" + httpRequestMessage);
var response = httpClient.SendAsync(httpRequestMessage).Result;
Console.Write("response:" + response);
return true;
}
I'm trying to POST a Document (any file type) to a GLPI server through API REST.
Here is what I'm doing:
private void button11_Click(object sender, EventArgs e)
{
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
var rcontent = string.Empty;
// HEADERS (URL + Access Tokens)
//string _ContentType = "multipart/form-data";
string _Uri = Properties.Settings.Default.GLPI_URL + "/Document/";
client.BaseAddress = new Uri(_Uri);
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_ContentType));
client.DefaultRequestHeaders.Add("Session-Token", Properties.Settings.Default.GLPI_SESSION_TOKEN);
client.DefaultRequestHeaders.Add("App-Token", Properties.Settings.Default.GLPI_APP_TOKEN);
// JSON Content (input string array with file uploaded informations)
JSON_C.DocumentAdder JSONContent = new JSON_C.DocumentAdder();
JSONContent.name = "sth";
JSONContent._filename = filebytes;
HttpContent _JSONContent = new StringContent("uploadManifest={\"input\": " + JsonConvert.SerializeObject(JSONContent).ToString() + "}", Encoding.UTF8, "application/json");
content.Add(_JSONContent);
// File Content in bytes
var fileContent = new ByteArrayContent(filebytes);
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("_filename") { FileName = filepath };
//fileContent.ReadAsByteArrayAsync();
content.Add(fileContent);
// Request
HttpResponseMessage reponse;
var _Method = new HttpMethod("POST");
reponse = client.PostAsync(_Uri, content).Result;
// Request response
rcontent = reponse.Content.ReadAsStringAsync().Result;
textBox2.Text = reponse.ToString() + Environment.NewLine + rcontent.ToString();
}
}
}
But this is what I got in response:
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Connection: close
Cache-Control: no-store, must-revalidate, no-cache
Date: Mon, 26 Nov 2018 12:50:09 GMT
Server: Apache/2.4.29
Server: (Ubuntu)
Content-Length: 61
Content-Type: application/json; charset=UTF-8
Expires: Mon, 26 Jul 1997 05:00:00 GM
}
With:
["ERROR_UPLOAD_FILE_TOO_BIG_POST_MAX_SIZE","The file seems too big"]
The file I'm trying to upload is 592bytes! Max overall limit in one request is 2Mo. And post_max_size in php.ini is "8M", the same result after I changed it to "0" (for no limit at all). And then set it to 20M to match upload_max_filesize (/etc/php/7.2/apache2/php.ini).
upload_max_filesize_.. is also "20M"
If anyone finding this post and needs help, here is how i managed to succeed :
After separatly creating a "Session-Token", and using "RestSharp".
// Upload
var RSClient = new RestClient(Properties.Settings.Default.GLPI_URL);
var request = new RestRequest("Document", Method.POST);
request.AddHeader("Session-Token", Properties.Settings.Default.GLPI_SESSION_TOKEN);
request.AddHeader("App-Token", Properties.Settings.Default.GLPI_APP_TOKEN);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "multipart/form-data");
request.AddQueryParameter("uploadManifest", "{\"input\": {\"name\": \"UploadFileTest\", \"_filename\": \"GiletsJaunes.jpg\"}}");
request.AddFile("test", #"C:\path\to\File.jpg");
IRestResponse response = RSClient.Execute(request);
var content = response.Content;
textBox2.Text = textBox2.Text + Environment.NewLine + content;
Details :
I couldn't use RestSharp.Authenticator = new SimpleAuthenticator for some reasons, so i added these Auth params with AddHeader.
I couldn't use a Serialised Json string in a new StringContent, because of AddQueryParameter, so i wrote it manually.
Alleluyah.
I am doing a POC on sending data to Azure event hub using C#. The data will be posted over http unlike the Eventhub client. As per the requirements I cam creating a SAStoken to be embedded in http header. However when posting I get 501, Unauthorized access error. Not sure where I am going wrong. Here is the code that I have written
public static async Task<HttpResponseMessage> SendDataUsingHttp()
{
// Namespace info.
var serviceNamespace = "myeventhubs";
var hubName = "eventhub1";
var url = string.Format("{0}/publishers/{1}/messages", hubName, 1);
//var url = string.Format("{0}/messages", hubName);
var baseUri = new
Uri(string.Format("https://{0}.servicebus.windows.net/"
, serviceNamespace));
var SharedAccessKeyName = "All";
var SharedAccessKey = "<shared access key>";
var sasToken =
createSasToken(baseUri.ToString(),SharedAccessKeyName,
SharedAccessKey);
var evtData = new
{
Temperature = new Random().Next(20, 50)
};
var payload = JsonConvert.SerializeObject(evtData);
// Create client.
var httpClient = new HttpClient
{
BaseAddress = baseUri
};
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Authorization = new
System.Net.Http.Headers.AuthenticationHeaderValue
("SharedAccessSignature", sasToken);
var content = new StringContent(payload, Encoding.UTF8);
content.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
HttpResponseMessage result = null;
try
{
result = await httpClient.PostAsync(url, content);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return result;
}
private static string createSasToken(string baseUri, string keyName,
string key)
{
TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
var week = 60 * 60 * 24 * 7;
var expiration = Convert.ToString((int)sinceEpoch.TotalSeconds +
week);
string stringToSign = HttpUtility.UrlEncode(baseUri) + "\n" +
expiration;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)); //--
var signature =
Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(
stringToSign)));
var sasToken = String.Format(CultureInfo.InvariantCulture,
"SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
HttpUtility.UrlEncode(baseUri), HttpUtility.UrlEncode(signature),
expiration, keyName);
return sasToken;
}
result
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1,
Content: System.Net.Http.StreamContent, Headers: {
Transfer-Encoding: chunked Strict- Transport-Security:
max-age=31536000 Date: Sun, 17 Jun 2018 08:35:43 GMT Server:
Microsoft-HTTPAPI/2.0 Content-Type: application/xml; charset=utf-8
}} Content: {System.Net.Http.StreamContent} Headers:
{Transfer-Encoding: chunked Strict-Transport-Security:
max-age=31536000 Date: Sun, 17 Jun 2018 08:35:43 GMT Server:
Microsoft-HTTPAPI/2.0
Based on your createSasToken method, it would generate the authorization header value with the following format:
Authorization: SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}
For your request, you also specify the following code:
System.Net.Http.Headers.AuthenticationHeaderValue("SharedAccessSignature", sasToken);
Using Fiddler to capture the network traces, you would find that your authorization header value in your sent request would look like this:
Authorization: SharedAccessSignature SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}
For your code, you need to adjust the format of your sasToken under the createSasToken method.
Moreover, the baseUri parameter of createSasToken method needs to be the full request path you are requesting. So you need to modify the related code under SendDataUsingHttp for generating the token as follows:
var sasToken =createSasToken(baseUri+url, SharedAccessKeyName, SharedAccessKey);
I'm new in using twitter API, I've successfully called:
https://api.twitter.com/1.1/statuses/user_timeline.json
api.twitter.com/1.1/followers/list.json
but when I call:
https://api.twitter.com/1.1/geo/search.json?query=Pakistan
I get Forbidden access.
Following is my request:
Method: GET, RequestUri: 'https://api.twitter.com/1.1/geo/search.json?query=Pakistan', Version: 1.1, Content: , Headers:
{
Authorization: Bearer xxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyzzzzzzzzzzzzzzzzzzzzzzzzz%aaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbb
}
And the response that I get is:
StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
strict-transport-security: max-age=631138519
x-connection-hash: 3a7f405036803861a700cef30f7b1e7f
x-response-time: 107
Date: Fri, 05 May 2017 03:18:15 GMT
Set-Cookie: guest_id=v1%3A149395429589966721; Domain=.twitter.com; Path=/; Expires=Sun, 05-May-2019 03:18:15 UTC
Server: tsa_o
Content-Length: 91
Content-Type: application/json; charset=utf-8
}
If you're interested in looking at my C# code that I'm using, here you go:
public async Task<IEnumerable<string>> GetTweetsByLatLong(double latitude, double longitude, int count, string accessToken = null)
{
if (accessToken == null)
{
accessToken = await GetAccessToken();
}
var requestUserTimeline = new HttpRequestMessage(HttpMethod.Get, string.Format("https://api.twitter.com/1.1/geo/search.json?query=Pakistan"));
requestUserTimeline.Headers.Add("Authorization", "Bearer " + accessToken);
var httpClient = new HttpClient();
HttpResponseMessage responseUserTimeLine = await httpClient.SendAsync(requestUserTimeline);
if (responseUserTimeLine.IsSuccessStatusCode)
{
var serializer = new JavaScriptSerializer();
dynamic json = ((serializer.Deserialize<object>(await responseUserTimeLine.Content.ReadAsStringAsync())) as Dictionary<string, object>).Values.ElementAt(0);
//new System.Collections.Generic.Mscorlib_DictionaryValueCollectionDebugView<string, object>((json as Dictionary<string, object>).Values).Items[0]
var enumerableTwitts = (json as IEnumerable<dynamic>);
if (enumerableTwitts == null)
{
return null;
}
return enumerableTwitts.Select(t => (string)(t["name"].ToString()));
}
else
{
return new string[] { responseUserTimeLine.ToString() };
}
}
public async Task<string> GetAccessToken()
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/oauth2/token ");
var customerInfo = Convert.ToBase64String(new UTF8Encoding().GetBytes(OAuthConsumerKey + ":" + OAuthConsumerSecret));
request.Headers.Add("Authorization", "Basic " + customerInfo);
request.Content = new StringContent("grant_type=client_credentials", Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.SendAsync(request);
string json = await response.Content.ReadAsStringAsync();
var serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(json);
return item["access_token"];
}
I believe it is because you are using Application-only authentication by providing a Bearer token.
See "Requires Authentication" in both
https://dev.twitter.com/rest/reference/get/geo/search
and
https://dev.twitter.com/rest/reference/get/statuses/user_timeline
And read https://dev.twitter.com/oauth
I'm trying to send the following request:
POST /messaging/registrations/(REGISTRATION_ID_FOR_DESTINATION_APP_INSTANCE)/messages HTTP/1.1
Host: api.amazon.com
Authorization: Bearer (MY_ACCESS_TOKEN)
Content-Type: application/json
X-Amzn-Type-Version: com.amazon.device.messaging.ADMMessage#1.0
Accept: application/json
X-Amzn-Accept-Type: com.amazon.device.messaging.ADMSendResult#1.0
{
"data":{"message":"value1","title":"value2"},
"consolidationKey":"Some Key",
"expiresAfter":86400
}
in order to get a response format like this:
HTTP/1.1 200
X-Amzn-Data-md5: t5psxALRTM7WN30Q8f20tw==
X-Amzn-RequestId: e8bef3ce-242e-11e2-8484-47f4656fc00d
Content-Type: application/json
X-Amzn-Type-Version: com.amazon.device.messaging.ADMSendResult#1.0
Content-Length: 308
{"registrationID":(REGISTRATION_ID_FOR_DESTINATION_APP_INSTANCE)}
to do that I tried with this code:
private void sendNotification(String registrationID,String message,
String title,String accessToken)
{
//registrationID content (REGISTRATION_ID_FOR_DESTINATION_APP_INSTANCE) that can vary
string url = "https://api.amazon.com/messaging/registrations/"+ registrationID +"/messages";
var client = new HttpClient();
//set Request headers
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Bearer", accessToken);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("X-Amzn-Type-Version",
"com.amazon.device.messaging.ADMMessage#1.0");
client.DefaultRequestHeaders.Add("X-Amzn-Accept-Type",
"com.amazon.device.messaging.ADMSendResult#1.0");
//the content of the message body
var content = new Dictionary<string, Object>();
content.Add("consolidationKey", "SyncNow");
content.Add("expiresAfter", 86400);
var data = new Dictionary<string, string>();
data.Add("message", message);
data.Add("title", title);
content.Add("data", data);
var result = client.PostAsJsonAsync<Dictionary<string, Object>>(url, content).Result;
}
As response I get StatusCode:400,ReasonPhrase:'Bad Request', I don't know why?
For detail about result which I got:
result {StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
x-amzn-RequestId: 1b943a1c-fe94-11e2-b963-71a537223b43
Vary: Accept-Encoding
Vary: User-Agent
Cneonction: close
Date: Tue, 06 Aug 2013 12:31:24 GMT
Content-Length: 34
Content-Type: application/json
}} System.Net.Http.HttpResponseMessage
result.RequestMessage {Method: POST,
RequestUri: 'https://api.amazon.com/messaging/registrations/(REGISTRATION_ID_FOR_DESTINATION_APP_INSTANCE)/messages',
Version: 1.1,
Content: System.Net.Http.ObjectContent`1[[System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],
[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],
Headers:
{
Authorization: Bearer (MY_ACCESS_TOKEN)
Accept: application/json
X-Amzn-Type-Version: com.amazon.device.messaging.ADMMessage#1.0
X-Amzn-Accept-Type: com.amazon.device.messaging.ADMSendResult#1.0
Content-Type: application/json; charset=utf-8
Content-Length: 98
}} System.Net.Http.HttpRequestMessage
I found an other solution that work perfectly .
private void sendNotification(String registrationID,String message,String title,String accessToken)
{
HttpWebRequest httpWReq =
(HttpWebRequest)WebRequest.Create("https://api.amazon.com/messaging/registrations/" + registrationID + "/messages");
Encoding encoding = new UTF8Encoding();
string postData = "{\"data\":{\"message\":\""+message+"\",\"title\":\""+title+"\"},\"consolidationKey\":\"Some Key\",\"expiresAfter\":86400}";
byte[] data = encoding.GetBytes(postData);
httpWReq.ProtocolVersion = HttpVersion.Version11;
httpWReq.Method = "POST";
httpWReq.ContentType = "application/json";//charset=UTF-8";
httpWReq.Headers.Add("X-Amzn-Type-Version",
"com.amazon.device.messaging.ADMMessage#1.0");
httpWReq.Headers.Add("X-Amzn-Accept-Type",
"com.amazon.device.messaging.ADMSendResult#1.0");
httpWReq.Headers.Add(HttpRequestHeader.Authorization,
"Bearer " + accessToken);
httpWReq.ContentLength = data.Length;
Stream stream = httpWReq.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
string s=response.ToString();
StreamReader reader = new StreamReader(response.GetResponseStream());
String jsonresponse = "";
String temp = null;
while ((temp = reader.ReadLine()) != null)
{
jsonresponse += temp;
}
}
Just looking at this quickly it seems like this line of code is wrong.
var result = client.PostAsJsonAsync<Dictionary<string, Object>>(url, data).Result;
based on fact that you're saying amazon wants the post json to look like this.
{"data":{"message":"value1","title":"value2"},"consolidationKey":"Some Key","expiresAfter":86400}
It seems like you should be passing your var content to the post rather than var data. I.e.
var result = client.PostAsJsonAsync<Dictionary<string, Object>>(url, content).Result;