I am working with an API that requires a call with the PATCH verb. I am trying to issue a request using the HttpClient object in C#. The request sends, however the JSON is not present in the body. Instead it is blank. Relevant code below.
var patch = new HttpMethod("PATCH");
var http = new HttpRequestMessage(patch, "https://apiendpoint");
var content = new StringContent(json, Encoding.UTF8, "application/json");
http.Content = content;
var result = client.SendAsync(http).Result;
This is my first time using SendAsync, so perhaps I am missing something else that needs to be set on the HttpRequestMessage?
Related
I'm fairly new to .NET's HTTPClient class, hence kindly excuse if I sounded noob. I'm tryin to replicate Postman's POST request in C# .Net and written following code. However I'm not getting any response but StatusCode: 404. Could someone assist understanding where I'm going wrong?
Also I'd like to understand, how do set Body in following code.
var httpClient = new HttpClient
{
BaseAddress = new Uri("https://testURL.com"),
Timeout = TimeSpan.FromMinutes(10)
};
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("audio/wav"));
httpClient.DefaultRequestHeaders.Add("Authorization", "Basic ldjfdljfdlfjdsjfdsl");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("model", "Test"),
});
var result = httpClient.PostAsync("api/v1/recognize", content).Result;
Here is what I'm doing in Postman and it works:
"Params" in Postman refers to query parameters which are appended to the URL. You'll see that the URL in Postman contains the parameters you added in the "Params" tab:
However, it seems those are just dummy values you've entered so perhaps you don't need them? In any case, the way you add query parameters to the request for HttpClient is a little different as it needs to be added to the URL.
After that you also need to add the audio file as content to your request. At the moment you're setting the "Accept" header to "audio/wav" but you probably want to set the "Content-Type" header instead (or are you expecting a WAV file to be returned in the response too?).
As far as I can see this is what you're missing:
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromMinutes(10);
// Set request headers
httpClient.DefaultRequestHeaders.Add("Authorization", "Basic ldjfdljfdlfjdsjfdsl");
// Set query parameters
var uriBuilder = new UriBuilder("https://testURL.com/api/v1/recognize");
uriBuilder.Query = "model=Test";
// Build request body
// Read bytes from the file being uploaded
var fileBytes = File.ReadAllBytes(wavFilePath);
// Create request content with metadata/headers to tell the
// backend which type of data (media type) is being uploaded
var byteArrayContent = new ByteArrayContent(fileBytes);
byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse("audio/wav");
// Wrap/encode the content as "multipart/form-data"
// See example of how the output/request looks here:
// https://dotnetfiddle.net/qDMwFh
var requestContent = new MultipartFormDataContent
{
{byteArrayContent, "audio", "filename.wav"}
};
var response = await httpClient.PostAsync(uriBuilder.Uri, requestContent);
}
I haven't tested this of course against your application, but it should be something along the lines of this. It might be that the backend doesn't expect "multipart/form-data" and just needs the "audio/wav". I can't see the output headers in your Postman screenshots, but if so, you can use byteArrayContent directly instead of wrapping it in MultipartFormDataContent.
Note: Don't use httpClient.PostAsync(...).Result. If you want to use the asynchronous method, you should await it. Depending on your code, using Result might give you problems if you're not careful. And remember to dispose the HttpClient after use (easiest solution is to use a using statement). If you plan on reusing the HttpClient for more requests, you can avoid disposing it until you're done.
It's a generic question, but I need help with my specific case.
I have a simple GET endpoint (see image) which I've tested with Postman and it works
It takes two id tokens in the header and thats it.
I've put breakpoints in the code and copied the exact instance of the ids into Postman and the request works, but executing from code, I get a 400 response
using (HttpClient client = new HttpClient())
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://*******.execute-api.ap-southeast-2.amazonaws.com/dev/uploads/image.jpg"),
Method = HttpMethod.Get,
};
var idToken = Application.Current.Properties["id_token"].ToString();
var accessToken = Application.Current.Properties["access_token"].ToString();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Add("Id-Token", idToken);
request.Headers.Add("Access-Token", accessToken);
var response = await client.SendAsync(request);
}
I've tried with and without the content-type header and makes no difference. Also doesn't matter if it's present in Postman
This is a Xamarin project which is where Application.Current.Properties comes from. I'm utilising other endpoints in the application are there are no issues with accessing the tokens like this.
I'm using HttpClient in .Net core 3.1. Most of my requests follow a similar pattern regardless of the HTTP method used:
build URL
build (optional) JSON payload
send request
await response
check status code
parse (optional) JSON response
so I've built a wrapper function that does all these things, and it takes the HTTP method as a parameter. However, when it comes to the "send request" step, I need to use a switch statement to invoke the appropriate method on HttpClient to invoke.
I'm sure that under the skin, get GetAsync() PostAsync() etc. are calling the same underlying function and passing the Http method as a parameter. but I can't see any way of calling it like this from the outside. It seems a strange omission as in my experience most HTTP libraries work that way.
Hope this will help you.
// For JsonConvert use Newtonsoft.Json
string url = "YourURL";
string body = JsonConvert.SerializeObject(BodyModel);
string headerParameter = "ASD123456789";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // Content-Type of request, it can be application/xml to other
client.DefaultRequestHeaders.Add("Device", headerParameter ); // first is name, second one is value
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url) // there you can have Get, Post, Put, Delete and etc. And every request needs to be configured by its settings
{
Content = new StringContent(body, Encoding.UTF8, "application/json")
};
HttpResponseMessage response = await client.SendAsync(request);
if ((int)response.StatusCode == 200)
{
string responseString = await response.Content.ReadAsStringAsync();
ResponseModel responseModel = JsonConvert.DeserializeObject<ResponseModel>(responseString);
}
I am using import.io to perform some simple query. I need to automate the calls because of the quantity of queries, therefore I am writing a c# client to run all of them.
I can use the API query "magic string" as template to build my queries, if I manually paste them in a browser I see the JSon of the response.
Calling the urls by code instead I always get the 401 unauthorized error.
I tried to set the url to a web browser control, but it reports that site cannot be accessed.
callingApi is a string with the full url, composed as such (instead of § I have the url to be scraped):
https://api.import.io/store/connector/(connector code)/_query?input=webpage/url:§_apikeyadmin=(my key)
(same problem with _apikey instead of _apikeyadmin)
I tried
WebRequest r = WebRequest.Create(callingApi);
r.Method = "GET";
using (var sr = r.GetResponse().GetResponseStream())
{
using (var reader = new StreamReader(sr))
{
var content = reader.ReadToEnd();
}
}
and also
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(callingApi);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync(callingApi).Result;
if (response.IsSuccessStatusCode)
... here I have error 401
Any advice please?
I am trying to retrieve a list object from Web api via code behind. I have the following code:
var update = new Update();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:xxxxx/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync("yada yada yada");
var result = response.Content.ReadAsStringAsync();
Where I'm getting confused is how to handle the data coming in so that it is in List<> format. I want to be able to enumerate through the List so I can manipulate the individual updates. When I hit the service with Fiddler, I get either a json or xml array depending on what I set the content-type to, so it works at that point. I just need some help figuring out some content negotiation. Any help is appreciated.