This is the POST Request, it works.
curl -X POST --header 'Accept: application/json'
'http://mywebsite.com/api/CompleteService?refId=12345&productPrice=600'
How to send this request using C# => HttpClient => client.PostAsync() method?
Two methods have been tried but both failed.
Method 1 (Failed, Response 404)
string url = "http://mywebsite.com/api/CompleteService";
string refId = "12345";
string price= "600";
string param = $"refId ={refId}&productPrice={price}";
HttpContent content = new StringContent(param, Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PostAsync(url, content).Result;
This would only work if API is to accept a request body, not query strings.
Method 2 (Failed, Response 404)
https://stackoverflow.com/a/37443799/7768490
var parameters = new Dictionary<string, string> { { "refId ", refId }, { "productPrice", price} };
var encodedContent = new FormUrlEncodedContent(parameters);
HttpResponseMessage response = client.PostAsync(url, encodedContent)
Apparently, None of the tried approaches put parameters in the URL!. You are posting on the below URL
"http://mywebsite.com/api/CompleteService"
However, something that works
string url = "http://mywebsite.com/api/CompleteService?";
string refId = "12345";
string price= "600";
string param = $"refId={refId}&productPrice={price}";
HttpContent content = new StringContent(param, Encoding.UTF8, "application/json");
Attach Parameters to URL and to get Response's Body, Use:
try
{
HttpResponseMessage response = await client.PostAsync(url + param, content);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
catch(HttpRequestException e)
{
Console.WriteLine("Message :{0} ",e.Message);
}
Related
I am not getting any response - no error, no bad request status, etc. - when I send a post request to this API route. postData is simply a JSON object. The funny thing here is this: When i send post data as a string instead of an object, I can get a response.
View the code below:
[HttpPost]
[Route("api/updateStaffs/")]
public async Task<object> UpdateStaff([FromBody] object postData)
{
string _apiUrl = "http://localhost:5000/system/getToken";
string _baseAddress = "http://localhost:5000/system/getToken";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var responseMessage = await client.PostAsync(_apiUrl, new StringContent(postData.ToString(), Encoding.UTF8, "application/json"));
if (responseMessage.IsSuccessStatusCode)
{
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = responseMessage.Content;
return ResponseMessage(response);
}
}
return NotFound();
}
No response:
var postData = new {
user = "test"
pass = "hey"
};
var responseMessage = await client.PostAsync(_apiUrl, new StringContent(postData.ToString(), Encoding.UTF8, "application/json"));
OR
var responseMessage = await client.PostAsync(_apiUrl, new StringContent("{}", Encoding.UTF8, "application/json"));
Will get response:
var responseMessage = await client.PostAsync(_apiUrl, new StringContent("blahblah", Encoding.UTF8, "application/json"));
The receiving API is a third-party application so I am unable to verify if this error is on the other end.
Thanks.
If you dont want to use PostAsJsonAsync
You need to serialize your anonymous type to JSON, the most common tool for this is Json.NET
var jsonData = JsonConvert.SerializeObject(postData);
Then you need to construct a content object to send this data, here we can use ByteArrayContent but you can use a different type
var buffer = System.Text.Encoding.UTF8.GetBytes(jsonData);
var byteContent = new ByteArrayContent(buffer);
Then send the request
var responseMessage = await client.PostAsync(_apiUrl, byteContent);
Figured out the issue. Have to use HttpVersion10 instead of HttpVersion11.
There has been a lot of similar questioning on this one but I could not get any answers working for me..
I am calling another api Post request from my controller..but I get a 400 bad request all the time..
public async Task<JsonResult> TestSCIMPost(AppAuth auth)
{
//Method 3:
HttpClient client = new HttpClient();
var jsonRequest = Newtonsoft.Json.JsonConvert.SerializeObject(auth);
var content = new StringContent(jsonRequest);
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/json");
HttpResponseMessage response = await client.PostAsJsonAsync(
URL, content);
return new JsonResult(response);
}
curl
curl -X POST "https://localhost:5001/api/Employee/api/Employee/TestSCIMPost" -H "accept: /" -H "Content-Type: application/json-patch+json" -d "{"client_id":"xyz","grant_type":"cc","client_secret":"abc","scope":"read"}"
I have tried a couple of other ways that I am listing below..
public async Task<JsonResult> TestSCIMPost(AppAuth auth)
{
/*var response = string.Empty;
var jsonRequest = Newtonsoft.Json.JsonConvert.SerializeObject(auth);
byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(jsonRequest);
var content = new ByteArrayContent(messageBytes);
//HttpContent c = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/json");
//content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
using (var client = new HttpClient())
{
//client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage result = await client.PostAsync(URL, content);
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}*/
//Method:2
//HttpClient client = new HttpClient();
//client.BaseAddress = new Uri(URL);
//client.DefaultRequestHeaders.Accept.Clear();
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
//var requestMessage = Newtonsoft.Json.JsonConvert.SerializeObject(auth);
//var content = new StringContent(requestMessage, Encoding.UTF8, "application/json");
//content.Headers.Remove("Content-Type");
//content.Headers.Add("Content-Type", "application/json");
//HttpResponseMessage result = await client.PostAsync(URL, content);
return new JsonResult(response);
}
The body is coming from auth (frontend that i am serializing and adding in my request)
What's going wrong here? Is it utf-encoding? how to fix?
One reason this can happen is if you are posting content in the body (as you are doing) where the parser expects to find it in the query.
So if you have something like this:
string url = "https://localhost:5001/api/Employee/TestSCIMPost";
var content = new StringContent("{\"client_id\":\"xyz\",\"grant_type\":\"cc\"}");
HttpResponseMessage response = await client.PostAsync(url, content);
Try changing it to this:
string url = "https://localhost:5001/api/Employee/TestSCIMPost?client_id=xyz&grant_type=cc";
var content = new StringContent("");
HttpResponseMessage response = await client.PostAsync(url, content);
I'm trying to access a rest endpoint, https://api.planet.com/auth/v1/experimental/public/users/authenticate. It is expecting json in the request body.
I can get the request to work in Postman but not using c#. Using postman I get the expected invalid email or password message but with my code I get "Bad Request" no matter I try.
Here is the code that makes the request
private void Login()
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://api.planet.com/");
client.DefaultRequestHeaders.Accept.Clear();
//ClientDefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
Data.User user = new Data.User
{
email = "myemail#company.com",
password = "sdosadf"
};
var requestMessage = JsonConvert.SerializeObject(user);
var content = new StringContent(requestMessage, Encoding.UTF8, "application/json");
var response = client.PostAsync("auth/v1/experimental/public/users/authenticate", content).Result;
Console.WriteLine(response.ToString());
}
catch (WebException wex )
{
MessageBox.Show(wex.Message) ;
}
}
class User
{
public string email;
public string password;
}
Here are screen grabs form Postman that are working
The way to get this to work was to alter the content header "content-type". By default HTTPClient was creating content-type: application/json;characterset= UTF8. I dropped and recreated the content header without the characterset section and it worked.
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/json");
The issue is you are trying to call an async method without waiting for the response using await method or var task = method; task.Wait() Therefore, when you end up doing response.ToString() it returns the text you are seeing.
One way to handle this within a non-async method would be to do the following:
var task = client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
task.Wait();
var responseTask = task.Content.ReadAsStringAsync();
responseTask.Wait();
Console.WriteLine(responseTask.Result);
Another way is to make the current method async by doing private async void Login() and then do:
var postResp = await client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
var response = await postResp.Content.ReadAsStringAsync();
Console.WriteLine(response);
Create a Method Like this...
static async Task<string> PostURI(Uri u, HttpContent c)
{
var response = string.Empty;
var msg = "";
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.PostAsync(u, c);
msg = await result.Content.ReadAsStringAsync();
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}
return response;
}
call In your Method
public void Login()
{
string postData ="{\"email\":\"your_email\",\"password\":\"your_password\"}";
Uri u = new Uri("yoururl");
var payload = postData;
HttpContent c = new StringContent(payload, Encoding.UTF8,"application/json");
var t = Task.Run(() => PostURI(u, c));
t.Wait();
Response.Write(t.Result);
}
I tried to make HTTP POST request with application/json in body to an external web-service from C# (.NET Core 2.2.104).
I've already read all similar questions in SO and wrote this code:
SignXmlRequestDto requestBody = new SignXmlRequestDto(p12, model.SignCertPin, model.Data);
string json = JsonConvert.SerializeObject(requestBody);
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = ncanNodeUrl,
Headers =
{
{ HttpRequestHeader.ContentType.ToString(), "application/json" }
},
Content = new StringContent(JsonConvert.SerializeObject(json))
};
var response = await httpClient.SendAsync(httpRequestMessage);
string responseString = await response.Content.ReadAsStringAsync();
I am getting an error from service, it says: "Invalid header Content-Type. Please set Content-Type to application/json". What is interesting here, if I simulate this request from Postman, then everything work well and I get successful response.
Updated: as #Kristóf Tóth suggested, I modified my code to:
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = ncanNodeUrl,
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
var response = await httpClient.SendAsync(httpRequestMessage);
string responseString = await response.Content.ReadAsStringAsync();
but it still gives me the same error message.
Content-Type is a content header. It should be set on the content, not the request itself. This can be done either using the StringContent(string,Encoding,string) constructor :
Content = new StringContent(JsonConvert.SerializeObject(json),Encoding.UTF8, "application/json")
or by setting the StringContent's Headers.ContentType property :
var content=new StringContent(JsonConvert.SerializeObject(json));
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
This might be an encoding issue. You should use JsonContent not StringContent OR you can do something similar:
// Serialize into JSON String
var stringPayload = JsonConvert.SerializeObject(payload);
// Wrap JSON StringContent which then can be used by the HttpClient class
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");
I want to start my VM using the post Uri as described here https://msdn.microsoft.com/en-us/library/azure/mt163628.aspx
Since i don't have body in my request i get 403 frobidden. I can make a get Request without problem. Here is my code
public void StartVM()
{
string subscriptionid = ConfigurationManager.AppSettings["SubscriptionID"];
string resssourcegroup = ConfigurationManager.AppSettings["ressourgroupename"];
string vmname = ConfigurationManager.AppSettings["VMName"];
string apiversion = ConfigurationManager.AppSettings["apiversion"];
var reqstring = string.Format(ConfigurationManager.AppSettings["apirestcall"] + "subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Compute/virtualMachines/{2}/start?api-version={3}", subscriptionid, resssourcegroup, vmname, apiversion);
string result = PostRequest(reqstring);
}
public string PostRequest(string url)
{
string content = null;
using (HttpClient client = new HttpClient())
{
StringContent stringcontent = new StringContent(string.Empty);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string token = GetAccessToken();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
HttpResponseMessage response = client.PostAsync(url, stringcontent).Result;
if (response.IsSuccessStatusCode)
{
content = response.Content.ReadAsStringAsync().Result;
}
}
return content;
}
i've also tried this in the PostRequest
var values = new Dictionary<string, string>
{
{ "api-version", ConfigurationManager.AppSettings["apiversion"] }
};
var posteddata = new FormUrlEncodedContent(values);
HttpResponseMessage response = client.PostAsync(url, posteddata).Result;
with url=string.Format(ConfigurationManager.AppSettings["apirestcall"] + "subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Compute/virtualMachines/{2}/start", subscriptionid, resssourcegroup, vmname);
I Get 400 Bad request
I found the solution. Needed to add role in Azure to allow starting/stopping the VM. That is why i received 4.3 forbidden.
Thank you