POST Request with json in c# - c#

I am attempting to do a POST request which I have got working through Postman but I am getting a 400 error when done from code.
I am trying to reach the POST endpoint from here: http://developer.oanda.com/rest-live-v20/order-ep/
Here is my code, does anything look incorrect or have I missed anything?
public void MakeOrder(string UID)
{
string url = $"https://api-fxpractice.oanda.com/v3/accounts/{UID}/orders";
string body = "{'order': {'units': '10000', 'instrument': 'EUR_USD', 'timeInForce': 'FOK', 'type': 'MARKET', 'positionFill': 'DEFAULT'}}";
using (WebClient client = new WebClient())
{
client.Headers.Add("Authorization", "Bearer 11699873cb44ea6260ca3aa42d2898ac-2896712134c5924a25af3525d3bea9b0");
client.Headers.Add("Content-Type", "application/json");
client.UploadString(url, body);
}
}
I'm very new to coding so apologies if it is something very simple.

use HttpClient from System.Net.Http:
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using (var httpClient = new HttpClient())
{
string url = $"https://api-fxpractice.oanda.com/v3/accounts/{UID}/orders";
string body = "{'order': {'units': '10000', 'instrument': 'EUR_USD', 'timeInForce': 'FOK', 'type': 'MARKET', 'positionFill': 'DEFAULT'}}";
var content = new StringContent(body , Encoding.UTF8, "application/json");
var result = httpClient.PostAsync(url, content).Result;
var contents = result.Content.ReadAsStringAsync();
}

I would suggest you to use HttpClient over WebClient. You can find here the difference.
using (var httpClient = new HttpClient())
{
string url = $"https://api-fxpractice.oanda.com/v3/accounts/{UID}/orders";
string body = "{'order': {'units': '10000', 'instrument': 'EUR_USD', 'timeInForce': 'FOK', 'type': 'MARKET', 'positionFill': 'DEFAULT'}}";
var content = new StringContent(body, Encoding.UTF8, "application/json");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTIzMDY0NTQsImlzcyI6IlRlc3QuY29tIiwiYXVkIjoiVGVzdC5jb20ifQ.c-3boD5NtOEhXNUnzPHGD4rY1lbEd-pjfn7C6kDPbxw");
var result = httpClient.PostAsync(url, content).Result;
var contents = result.Content.ReadAsStringAsync();
}

Related

How to switch from HttpWebRequest to HttpClient?

I'm trying to send a request through HttpClient and read a response. This is the curl from which I tried to do this:
curl -H "Content-Type: application/json" --data \
'{comment: {text: "vulgar content"},
languages: ["en"],
requestedAttributes: {TOXICITY:{}} }' \
https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=YOUR_KEY_HERE
I've tried something likes this:
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=YOUR_KEY_HERE"))
{
request.Content = new StringContent("{comment: {text: \"vulgar\"},\n languages: [\"en\"],\n requestedAttributes: {TOXICITY:{}} }");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
using var response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
}
}
And this:
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Content-Type", "text/plain");
HttpContent postData = new StringContent("{comment: {text: \"what kind of idiot name is foo?\"},\n languages: [\"en\"],\n requestedAttributes: {TOXICITY:{}} }");
HttpResponseMessage response = await client.PostAsync("https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=AIzaSyCZdLeFtJhbqD9_WJ2Q4UiDB-THRzQhp5g", postData);
if (response.IsSuccessStatusCode)
{
var x = await response.Content.ReadAsStringAsync();
}
else
{
//Do something when request fails
return true;
}
}
However both of those snippets just break on the response part. No exception, no communicates, console says programe ends with code 0. But sending it via HttpWebRequest works just fine:
var url = "https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=YOUR_KEY_HERE";
var httpRequest = (HttpWebRequest)WebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.ContentType = "application/json";
var data = #"{comment: { text: ""what kind of idiot name is foo?""},languages: [""en""], requestedAttributes: {TOXICITY:{}} }";
using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
{
streamWriter.Write(data);
}
var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Console.WriteLine(httpResponse.StatusCode);
My question is, what am I doing wrong in sending it through HttpClient? I'm replacing YOUR_KEY_HERE with my API key.
Okay, so following Jon Skeet advice on providing reproducable example, I noticed that my Task wasn't marked as async. So I solved it by making a request in async Task method:
public async Task<string> FirstSnippet()
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=AIzaSyCZdLeFtJhbqD9_WJ2Q4UiDB-THRzQhp5g"))
{
request.Content = new StringContent("{comment: {text: \"vulgar\"},\n languages: [\"en\"],\n requestedAttributes: {TOXICITY:{}} }");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
using var response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
return body;
}
}
}
And calling method in Main:
Program p = new();
Console.WriteLine(await p.FirstSnippet());

Azure DevOps REST API

I have read the Azure DevOPS REST API documentation and tried to implement it to my Web Application multiple times but to no avail. I have no experience using REST API's and I would appreciate if someone could guide me into the right direction.
I am trying to create a POST Request for Azure DevOps Repositories and wish to create a new repository through the API method. I have read the documentation on this, but I have no idea how to implement this in my own project. I understand how I need to create a connection to the API, but no idea how and where I write the Request Body for this method. I would like to know how I specify the name of the new repository. I'm actually very clueless and have no idea how to use the REST API in general.
I am using Visual Studio with .NET Core 3.0 and plan to use this with React.js
Here's the code I'm working with so far, and I have no idea where to go from here:
public class AzureDevOps {
public static async void GetRepositories()
{
try
{
var personalaccesstoken = "PAT_FROM_WEBSITE";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalaccesstoken))));
using (HttpResponseMessage response = await client.GetAsync(
"https://dev.azure.com/{organization}/_apis/git/repositories?api-version=5.1"))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
I would appreciate any clarification on this matter, as well as some examples on how to use the REST API. Thanks in advance!
You should use POST method to create a repository. Check the API here:
https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories/create?view=azure-devops-rest-5.1
The code should look like:
var PAT = "xxxxx";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", PAT))));
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "https://dev.azure.com/{organization}/{project}/_apis/git/repositories?api-version=5.1");
requestMessage.Content = new StringContent("{\"name\": \"RepositoryName\",\"project\": {\"id\": \"xxxxxxx\"}}", Encoding.UTF8, "application/json");
using (HttpResponseMessage response = client.SendAsync(requestMessage).Result)
{
response.EnsureSuccessStatusCode();
}
}
Update:
var PAT = "xxxxx";
var body = new
{
name = "RepositoryName",
project = new
{
id = "xxxxxxx"
}
};
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", PAT))));
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "https://dev.azure.com/{organization}/{project}/_apis/git/repositories?api-version=5.1");
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
using (HttpResponseMessage response = client.SendAsync(requestMessage).Result)
{
response.EnsureSuccessStatusCode();
}
}

include raw text in http get request in c# backend code

I have this code:
client.BaseAddress = new Uri("https://sandbox-quickbooks.api.intuit.com/v3/company/1232/vendor/70?minorversion=8");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization
= new AuthenticationHeaderValue("Bearer", "bLpuw.vjbvIP_P7Vyj4ziSGa3Ohg");
using (HttpResponseMessage response = client.PostAsync("https://sandbox-quickbooks.api.intuit.com/v3/company/1232/query?minorversion=8").Result)
{
using (HttpContent content = response.Content)
{
var json = content.ReadAsStringAsync().Result;
}
}
Per the quickbooks api Postman sample they include raw text query in the http post action.
Example:
How can I include the raw text in my c# post request?
You need to pass content to PostAsync method just like this
var myContent = "your string in here";
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
using (HttpResponseMessage response = client.PostAsync("https://sandbox-quickbooks.api.intuit.com/v3/company/1232/query?minorversion=8",bytecontent).Result)
{
using (HttpContent content = response.Content)
{
var json = content.ReadAsStringAsync().Result;
}
}
Create a StringContent() with the text in it and pass it to the PostAsync().
You might need to check what Content-Type header is expected and pass that to the StringContent constructor as well.
E.g.
using (var requestContent = new StringContent(“any text”, Encoding.UTF8, “text/plain”))
{
... httpClient.PostAsync(url, requestContent)...
}
client.BaseAddress = new Uri("https://sandbox-quickbooks.api.intuit.com/v3/company/1232/vendor/70?minorversion=8");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization
= new AuthenticationHeaderValue("Bearer", "bLpuw.vjbvIP_P7Vyj4ziSGa3Ohg");
var postContent = new StringContent("myContent");
using (HttpResponseMessage response = client.PostAsync("https://sandbox-quickbooks.api.intuit.com/v3/company/1232/query?minorversion=8", postContent).Result)
{
using (HttpContent content = response.Content)
{
var json = content.ReadAsStringAsync().Result;
}
}
Also, please be aware that you have some wrong use of the Async methods, you should always await instead of using the blocking Result property from the task.

Why HttpClient uses an incorrect requestUri in post request?

When I use HttpClient class to send a POST request to an API URL, it modifies the URL that I've passed to it. For example, when I use the main API URL the RequestUri is incorrect and I receive the not found response. This problem happens when I use api word in the URL !!
Concept:
The Incorrect, modified URL:
Url: https://sandbox-api.alopeyk.com/api/v2/order
Request Url: https://sandbox-api.alopeyk.com
The Correct, and expected URL (This is the one I specify)
Url: https://google.com/api/v2/order
Request Url: https://google.com/api/v2/order
Code:
public async Task<CreateOrderResponse> CreateOrderAsync(CreateOrderRequest request)
{
var endPoint = EndPointFactory<CreateOrderResponse>.Build(HttpMethod.Post);
var jsonString = JsonConvert.SerializeObject(request);
var url = new Uri("https://sandbox-api.alopeyk.com");
var encodedFrom = new StringContent(jsonString);
var httpClient = endPoint.GetHttpClient(url);
var httpResponse = await httpClient.PostAsync("api/v2/orders", encodedFrom).ConfigureAwait(false);
// when use api it's https://sandbox-api.alopeyk.com it should be https://sandbox-api.alopeyk.com/api/v2/orders
// when use other host name for example it's correct
var requesturl = httpResponse.RequestMessage.RequestUri;
return await httpResponse.Content.ReadAsAsync<CreateOrderResponse>().ConfigureAwait(false);
}
// in the EndPoint class
public HttpClient GetHttpClient(Uri url)
{
return new Http.HttpClientFactory().GetOrCreate(Url, Headers);
}
If you want to see HttpClientFactory it's here.
The HttpClient have a problem with my main hostname that it's https://sandbox-api.alopeyk.com
Your Uri must end with a slash like this:
var url = new Uri("https://sandbox-api.alopeyk.com/");
That's a rather silly restriction of HttpClient.
Try this code:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://sandbox-api.alopeyk.com");
HttpResponseMessage response = client.PostAsync("api/v2/orders", new StringContent(jsonString, Encoding.UTF8, "text/json")).Result;
if (response.IsSuccessStatusCode)
{
// Parse the response body. Blocking!
var responseData = response.Content.ReadAsStringAsync().Result;
}
You can try with this code
HttpResponseMessage response = null;
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Post,"https://sandbox-api.alopeyk.com/api/v2/orders"))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", /*token herer*/);
var data = new StringContent(JsonConvert.SerializeObject(request, Encoding.UTF8, "application/json"));
request.Content = data;
response = await client.SendAsync(request);
}
}

Set Authorization/Content-Type headers when call HTTPClient.PostAsync

Where can I set headers to REST service call when using simple HTTPClient?
I do :
HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
{"id", "111"},
{"amount", "22"}
};
var content = new FormUrlEncodedContent(values);
var uri = new Uri(#"https://some.ns.restlet.uri");
var response = await client.PostAsync(uri, content);
var responseString = await response.Content.ReadAsStringAsync();
UPD
Headers I want to add:
{
"Authorization": "NLAuth nlauth_account=5731597_SB1, nlauth_email=xxx#xx.com, nlauth_signature=Pswd1234567, nlauth_role=3",
"Content-Type": "application/json"
}
Should I do the following?
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "NLAuth nlauth_account=5731597_SB1, nlauth_email=xxx#xx.com, nlauth_signature=Pswd1234567, nlauth_role=3","Content-Type":"application/json");
The way to add headers is as follows:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");
Or if you want some custom header:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("HEADERNAME", "HEADERVALUE");
This answer has SO responses already, see below:
Adding headers when using httpClient.GetAsync
Setting Authorization Header of HttpClient
UPDATE
Seems you are adding two headerrs; authorization and content type.
string authValue = "NLAuth nlauth_account=5731597_SB1,nlauth_email=xxx#xx.com, nlauth_signature=Pswd1234567, nlauth_role=3";
string contentTypeValue = "application/json";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authValue);
client.DefaultRequestHeaders.Add("Content-Type", contentTypeValue);
I know this was asked a while ago, but Juan's solution didn't work for me.
(Also, pretty sure this question is duplicated here.)
The method that finally worked was to use HttpClient with HttpRequestMessage and HttpResponseMessage.
Also note that this is using Json.NET from Newtonsoft.
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http.Headers;
using Newtonsoft.Json;
namespace NetsuiteConnector
{
class Netsuite
{
public void RunHttpTest()
{
Task t = new Task(TryConnect);
t.Start();
Console.WriteLine("Connecting to NS...");
Console.ReadLine();
}
private static async void TryConnect()
{
// dummy payload
String jsonString = JsonConvert.SerializeObject(
new NewObj() {
Name = "aname",
Email = "someone#somewhere.com"
}
);
string auth = "NLAuth nlauth_account=123456,nlauth_email=youremail#somewhere.com,nlauth_signature=yourpassword,nlauth_role=3";
string url = "https://somerestleturl";
var uri = new Uri(#url);
HttpClient c = new HttpClient();
c.BaseAddress = uri;
c.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", auth);
c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, url);
req.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
HttpResponseMessage httpResponseMessage = await c.SendAsync(req);
httpResponseMessage.EnsureSuccessStatusCode();
HttpContent httpContent = httpResponseMessage.Content;
string responseString = await httpContent.ReadAsStringAsync();
Console.WriteLine(responseString);
}
}
class NewObj
{
public string Name { get; set; }
public string Email { get; set; }
}
}
The other answers do not work if you are using an HttpClientFactory, and here's some reasons why you should. With an HttpClientFactory the HttpMessages are reused from a pool, so setting default headers should be reserved for headers that will be used in every request.
If you just want to add a content-type header you can use the alternate PostAsJsonAsync or PostAsXmlAsync.
var response = await _httpClient.PostAsJsonAsync("account/update", model);
Unfortunately I don't have a better solution for adding authorization headers than this.
_httpClient.DefaultRequestHeaders.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer {bearer}");
On dotnet core 3.1 trying to run the top answer:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Content-Type", "application/x-msdownload");
threw an exception: System.InvalidOperationException: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.
What worked for me was to instead set HttpContent.Headers -> HttpContentHeaders.ContentType property with a MediaTypeHeaderValue value:
HttpClient client = new HttpClient();
var content = new StreamContent(File.OpenRead(path));
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-msdownload");
var post = client.PostAsync(myUrl, content);
I prefer to cache the httpClient so I avoid setting headers which could affect other requests and use SendAsync
var postRequest = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
postRequest.Headers.Add("Content-Type", "application/x-msdownload");
var response = await httpClient.SendAsync(postRequest);
var content = await response.Content.ReadAsStringAsync();

Categories

Resources