Send POST request from webapi c# to onesignal url - c#

I'm very new on this and I need some help. I'm trying to send a notification from my webapi to my app. To do this a need just send a post to the url("https://onesignal.com/api/v1/notifications") with some informations (Header from authorization and content-type). But when I send the post it takes a long and and I just get The operation timeout has been reached, no message errors that could help me. I tryed the code from onesignal's documentation from asp.net solutions but isn't worked for me. Anyone can help? Or just help how can I trace the error with my requisiton? After try the code from onesignal's documentation I decided use the following code(both codes had the same behavior):
using (var client = new HttpClient())
{
var url = new Uri("https://onesignal.com/api/v1/notifications");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "Rest ID");
var obj = new
{
app_id = "APP ID",
contents = new { en = "English Message" },
included_segments = new string[] { "All" }
};
var json = JsonConvert.SerializeObject(obj);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
}

For some reason is taking a long time to send a notification and return some response for me. So I increase the timeout to wait the response and don't get a task cancelled. Hope help someone.

Related

Sending custom Content-Type using HttpClient C# .Net6

Hello Stackoverflow community. I hope someone here can help me!!
I'm trying to integrate with the Zoopla API that requires the post request to send the following customized content type. (I've got the certificate side of things working fine).
application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json
I've tried the following approaches without any success (they all result in the following error)
System.FormatException: 'The format of value 'application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json' is invalid.'
Initial approach was to set it within the content of the RequestMessage
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list"),
Method = HttpMethod.Post,
Content = new StringContent(jsonBody, Encoding.UTF8, "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json")
};
When that didn't work I tried to set it via the default headers (the client below is from the ClientFactory)
client.DefaultRequestHeaders.Add("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
My final attempt was to set it without validation
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
I've just tried something else which unfortunately didn't work
string header = "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json";
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(header));
I am well and truly stumped!! HELP!! :-)
Content-Type is set on the content, not in DefaultRequestHeaders. You may try using TryAddWithoutValidation on the request content:
var content = new StringContent("hello");
content.Headers.ContentType = null; // zero out default content type
content.Headers.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
var client = new HttpClient(); // note: use IHttpClientFactory in non-example code
var response = await client.PostAsync("https://postman-echo.com/post", content);
Console.WriteLine(response.StatusCode); // OK
Console.WriteLine(await response.Content.ReadAsStringAsync());
// {"args":{},"data":{},"files":{},"form":{},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-6345b568-22cc353761f361483f2c3157","content-length":"5","content-type":"application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json"},"json":null,"url":"https://postman-echo.com/post"}

Calling Get Request with Json Body using httpclient

I came with an issue this morning where the Api which I am calling is a Get Method but to get Get the Data from it I had to send the json body this is working good when I am testing it in the post man but I am not able to implement it in my project where I am calling this using HttpClient
here is the screenshot of post
It also have a bearer token which I pass in Authorization
Now when I am try to implement this at client side here is my code
var stringPayload = JsonConvert.SerializeObject(json);
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://myapiendpoint/serviceability/"),
Content = new StringContent(stringPayload, Encoding.UTF8, "application/json"),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
when I call this method using this code I get
System.Net.HttpStatusCode.MethodNotAllowed - Status code 405
I also tried changing this line
Method = HttpMethod.Get to Method = HttpMethod.Post
but still getting same error
I know this is bad implementation at API Side the request ideally should be POST but changing this is not in my hand and hence need to find the solution
almost search all over and trying all the variant of using GET Method finally the solution which worked for me in this case was this
var client = new HttpClient();
client.BaseAddress = new Uri("https://baseApi/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", token));
var query = new Dictionary<string, string>
{
["pickup_postcode"] = 400703,
["delivery_postcode"] = 421204,
["cod"] = "0",
["weight"] = 2,
};
var url = "methodurl";
var response = await client.GetAsync(QueryHelpers.AddQueryString(url, query));
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<MyModel>(responseBody);
Got QueryHelpers from Microsoft.AspNetCore.WebUtilities package

403 error when trying to get data from Reddit API

I am using oAuth to authenticate my app. I managed to get a code, access_token and refresh_token. So the next step would be trying to get info about the current user.
public async void GetCurrentUser()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken);
var response = await client.GetAsync("https://oauth.reddit.com/api/v1/me");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
}
}
}
This is the method I am using to do that. However the response is always an 403 (Forbidden) error code. Any idea what could be wrong? The access_token is what I got when I made a request to https://oauth.reddit.com/api/v1/access_token
I think the token is correct because when I create the same request with Fiddler it works.
ANSWER:
Fixed it by adding a custom user-agent
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, _endpointUri + "me");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
request.Headers.Add("User-Agent", Uri.EscapeDataString("android:com.arnvanhoutte.redder:v1.2.3 (by /u/nerdiator)"));
var response = await client.SendAsync(request);

How to create new NoteBook with OneNote API

I'm getting a "Bad Request" error 400 when I try to create a new Notebook. Below is my code, I think it is the PagesEndPoint Uri but I have tried all combinations. I can use the apigee console app, but cannot detemine how to make a C# Windows app Post message.
async public Task<StandardResponse> CreateNewNotebook(string newNotebookName)
{
Uri PagesEndPoint = new Uri("https://www.onenote.com/api/v1.0/notebooks?notebookName="+newNotebookName.ToString());
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (IsAuthenticated)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authClient.Session.AccessToken);
}
string date = GetDate();
string simpleHtml = "<html>"+"<head>"+"<title>A simple page created with an image1 on it</title>" +"<meta name=\"created\" content=\"" + date + "\" />" +
"</head>" +"<body>" +"<h1>This is a page with an image on it</h1>" +"</body>" +"</html>";
HttpResponseMessage response;
HttpRequestMessage createMessage = new HttpRequestMessage(HttpMethod.Post, PagesEndPoint)
{
Content = new StringContent(simpleHtml, System.Text.Encoding.UTF8, "text/html")
};
response = await client.SendAsync(createMessage);
tbResponse.Text = response.ToString();
return await TranslateResponse(response);
}
I've tried with this new code, but still not working. The links to the documentation show the elements to use, but not how to use them to make C# method.
Here is my latest code.
async public Task<StandardResponse> CreateJsonNotebook(string newNotebookName)
{
string postData = "{name: \"NewNotebookName\"}";
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (IsAuthenticated)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authClient.Session.AccessToken);
}
StreamWriter requestWriter;
var webRequest = System.Net.WebRequest.Create("https://www.onenote.com/api/v1.0/notebooks") as HttpWebRequest;
HttpResponseMessage response;
response = await client.SendAsync(postData);
tbResponse.Text = response.ToString();
return await TranslateResponse(response);
}
there are a few things incorrect with your latest code pasted above.
Here's the modified version that I got working :
public async Task<StandardResponse> CreateJsonNotebook(string newNotebookName)
{
var client = new HttpClient();
string postData = "{name: \"" + newNotebookName + "\"}";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (IsAuthenticated)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",
_authClient.Session.AccessToken);
}
StreamWriter requestWriter;
var webRequest = new HttpRequestMessage(HttpMethod.Post, "https://www.onenote.com/api/v1.0/notebooks")
{
Content = new StringContent(postData, Encoding.UTF8, "application/json")
};
HttpResponseMessage response;
response = await client.SendAsync(webRequest);
return await TranslateResponse(response);
}
Notice that:
I didn't combine usage of HttpClient and HttpWebRequest.
When creating the HttpWebRequest.Content, I set the mediaType to "application/json"
Also client.SendAsync() used the HttpRequestMessage and not the postData string.
You're right - the URL isn't quite right. You can't actually create a page and a notebook at the same time - they require two different calls.
To create a notebook, the URL you should post to is:
https://www.onenote.com/api/v1.0/notebooks
The notebook is created with the content of the body, which should be JSON. (Make sure you include CONTENT-TYPE: application/json in the header).
The body should look like:
{
name: "New Notebook Name"
}
You can then create a section in the notebook with the ID in the response. Once you get the ID of a new section, you can then post a page to that section.
More information can be found here: http://msdn.microsoft.com/en-us/library/office/dn790583(v=office.15).aspx
The way you are calling the API is incorrect. You shouldn't be putting a notebookName query parameter in the endpoint. Instead, you should just post to https://www.onenote.com/api/v1.0/notebooks with a JSON body. The JSON body should be
{ name: "New notebook name" }
You can see this blog post for an example.
-- James

Making a call to a Web Api with a JObject in the body

I want to, in code behind, call a Web Api I've built and save some data that I have stored in the following JObject:
var json = new JObject(
new JProperty("firstName", txtFirstName.Text),
new JProperty("lastName", txtLastName.Text),
new JProperty("companyName", txtCompanyName.Text),
new JProperty("email", txtEmail.Text),
new JProperty("phone", txtPhone.Text)
);
Problem is, I'm not sure the best way to go about this. I've found a plethora of examples that are close to the answer, but not quite what I'm looking for. So, how would someone construct an http call to a web api(in C#) and have the aforementioned JObject be posted in the body of the message? I wouldn't necessarily need anything returned, except maybe a generic success or failure message. I appreciate any help given.
Here's an example using System.Net.HttpClient
string jsonText = json.ToString();
using (var client = new HttpClient())
{
var httpContent = new StringContent(jsonString);
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
HttpResponseMessage message = await client.PostAsync("http://myWebUrl/send", httpContent);
}
I ended up changing the json into a .net object and got my problem solved.
using System.Net.Http;
using System.Net.Http.Headers;
var userData = new User()
{
firstName = txtFirstName.Text,
lastName = txtLastName.Text,
companyName = txtCompanyName.Text,
email = txtEmail.Text,
phone = txtPhone.Text
};
client.BaseAddress = new Uri("http://yourBaseUrlHere");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsJsonAsync("requestUrlHere", user);
if (response.IsSuccessStatusCode)
{
//Success code
}

Categories

Resources