I need to add http headers to the HttpClient before I send a request to a web service. How do I do that for an individual request (as opposed to on the HttpClient to all future requests)? I'm not sure if this is even possible.
var client = new HttpClient();
var task =
client.GetAsync("http://www.someURI.com")
.ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
var jsonTask = response.Content.ReadAsAsync<JsonObject>();
jsonTask.Wait();
var jsonObject = jsonTask.Result;
});
task.Wait();
Create a HttpRequestMessage, set the Method to GET, set your headers and then use SendAsync instead of GetAsync.
var client = new HttpClient();
var request = new HttpRequestMessage() {
RequestUri = new Uri("http://www.someURI.com"),
Method = HttpMethod.Get,
};
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
var task = client.SendAsync(request)
.ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
var jsonTask = response.Content.ReadAsAsync<JsonObject>();
jsonTask.Wait();
var jsonObject = jsonTask.Result;
});
task.Wait();
When it can be the same header for all requests or you dispose the client after each request you can use the DefaultRequestHeaders.Add option:
client.DefaultRequestHeaders.Add("apikey","xxxxxxxxx");
To set custom headers ON A REQUEST, build a request with the custom header before passing it to httpclient to send to http server.
eg:
HttpClient client = HttpClients.custom().build();
HttpUriRequest request = RequestBuilder.get()
.setUri(someURL)
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.build();
client.execute(request);
Default header is SET ON HTTPCLIENT to send on every request to the server.
Related
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
I am trying to send a POST request from my ASP.NET Core Web API Project but the request is never sent. The method gets executed with no errors but the request never gets sent out from the async method.
My Implementation:
public async void notify(String message)
{
String url = "MY_WEBSERVICE_URL";
var client = new HttpClient();
client.BaseAddress = new Uri(url);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("application/x-www-form-urlencoded;charset=UTF-8",
Encoding.UTF8, "application/json");
Byte[] byteArray = Encoding.UTF8.GetBytes("{\"text\":\"" + message + "\"}");
request.Content.Headers.ContentLength = byteArray.Length;
await client.SendAsync(request).ContinueWith(responseTask =>
{
Console.WriteLine("Response: {0}", responseTask.Result);
});
}
Is this the proper way of making a POST request from a Core Web API project? Thank you in advance
First of all, there is a dedicated method PostAsync in the HttpClient class ( or even PostAsJsonAsync extension) which you can use to send POST requests without creating HttpRequstMessage manually.
Now about your code - I believe you want to post following JSON string:
{"text":"someMessage"}
You should set this string as a content of StringContent which you are sending:
var json = "{\"text\":\"" + message + "\"}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
Currently you are trying to post mediatype string as a value to your API endpoint. Of course it cannot be deserialized into your model.
Note1: StringContent will automatically add Content-Length header with the appropriate value. You should not do that manually.
Note2: Unless this is an event handler, you should not use async void - use async Task instead.
Same task with PostAsJsonAsync usage will look like:
public async Task Notify(string message)
{
var string url = "MY_WEBSERVICE_URL";
var client = new HttpClient();
client.BaseAddress = new Uri(url);
var notification = new Notification { Text = message }; // use some model class
var resonse = await client.PostAsJsonAsync("relativeAddress", notification);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
}
}
In this case, your model will be automatically serialized into JSON, appropriate content will be created and POST request will be sent.
Try Adding [IgnoreAntiforgeryToken] on top of the Post Action like this
I am using RestSharp to post some data to a url. I am monitoring this operation using fiddler. when I use Simple .net HttpClient with this code:
using (var client = new HttpClient())
{
var values = new Dictionary<string, string> {
{ "par1", "1395/11/29" },
{ "par2", "2" }};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://someurl.com/resource", content);
var responseString = await response.Content.ReadAsStringAsync();
}
every thing is good and this return true result. but when i try to use RestSharp with this code:
RestSharp.RestRequest request = new RestSharp.RestRequest("/resource");
request.AddParameter("par1", val, RestSharp.ParameterType.RequestBody);
request.AddParameter("par2", val, RestSharp.ParameterType.RequestBody);
request.AddHeader("Origin", "http://someurl.com");
request.Method = RestSharp.Method.POST;
RestSharp.RestClient client = new RestSharp.RestClient("http://someurl.com");
var response = client.Execute(request);
then fiddler show me the request sent by GET method instead of POST?
I check another time my fiddler and found this issue:
Content-Type: par1
why this is happening for me?
Change your ParameterType argument to GetOrPost and it will work
request.AddParameter("par1", val, RestSharp.ParameterType.GetOrPost);
request.AddParameter("par2", val, RestSharp.ParameterType.GetOrPost);
Initialize Request as POST with JSON.
var client = new RestClient(PreUri);
var request = new RestRequest(Uri, Method.POST) {RequestFormat = DataFormat.Json};
Add object in body
request.AddBody(obj);
Execute
var cancellationTokenSource = new CancellationTokenSource();
var response = await client.ExecuteTaskAsync(request, cancellationTokenSource.Token);
I was stupidly doing mistake to call "client.Get" instead of "client.Post". May be this post helps other.
var client = new RestClient("https://someservice.com");
var request = new RestRequest("/token/", Method.POST, DataFormat.Json).AddJsonBody(SomeObject);
var response = client.Get(request);
I was expecting this code to make POST request. Because i specified it as Method.POST.
But after a few hours, i saw my mistake. Yeas i was specifying the method. But just after i am calling client.Get(request); This changes the metod to GET.
So, the right way to use POST request is like follows:
var client = new RestClient("https://someservice.com");
var request = new RestRequest("/token/", DataFormat.Json).AddJsonBody(SomeObject);
var response = client.Post(request);
I use codes below to send POST request to a server:
string url = "http://myserver/method?param1=1¶m2=2"
HttpClientHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
HttpResponseMessage response = await httpClient.SendAsync(request);
I don't have access to the server to debug but I want to know, is this request sent as POST or GET?
If it is GET, How can I change my code to send param1 & param2 as POST data (not in the URL)?
A cleaner alternative would be to use a Dictionary to handle parameters. They are key-value pairs after all.
private static readonly HttpClient httpclient;
static MyClassName()
{
// HttpClient is intended to be instantiated once and re-used throughout the life of an application.
// Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads.
// This will result in SocketException errors.
// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.7.1
httpclient = new HttpClient();
}
var url = "http://myserver/method";
var parameters = new Dictionary<string, string> { { "param1", "1" }, { "param2", "2" } };
var encodedContent = new FormUrlEncodedContent (parameters);
var response = await httpclient.PostAsync (url, encodedContent).ConfigureAwait (false);
if (response.StatusCode == HttpStatusCode.OK) {
// Do something with response. Example get content:
// var responseContent = await response.Content.ReadAsStringAsync ().ConfigureAwait (false);
}
Also dont forget to Dispose() httpclient, if you dont use the keyword using
As stated in the Remarks section of the HttpClient class in the Microsoft docs, HttpClient should be instantiated once and re-used.
Edit:
You may want to look into response.EnsureSuccessStatusCode(); instead of if (response.StatusCode == HttpStatusCode.OK).
You may want to keep your httpclient and dont Dispose() it. See: Do HttpClient and HttpClientHandler have to be disposed?
Edit:
Do not worry about using .ConfigureAwait(false) in .NET Core. For more details look at https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html
This is how I use it for DI:
using HttpClient httpClient = clientFactory.CreateClient("name set in builder host");
// httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Token {token}");
HttpResponseMessage? res = await httpClient!.PostAsync(url, content);
try
{
res.EnsureSuccessStatusCode();
return res;
}
catch (Exception)
{
// Add error handling
}
content is:
List<KeyValuePair<string, string>> values = new()
{
new KeyValuePair<string, string>("data", "value")
};
FormUrlEncodedContent requestContent = new(values);
and clientFactory is the interface:
IHttpClientFactory
msdn interface
As Ben said, you are POSTing your request ( HttpMethod.Post specified in your code )
The querystring (get) parameters included in your url probably will not do anything.
Try this:
string url = "http://myserver/method";
string content = "param1=1¶m2=2";
HttpClientHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
HttpResponseMessage response = await httpClient.SendAsync(request,content);
HTH,
bovako
i am looking for a simple example using .net HttpClient to POST parameters and add headers. This is super easy in RestSharp but so far i cannot see a clear way how to do this with the HttpClient.
If you want to modify request headers for every request then the easiest way to do it is by setting the DefaultRequestHeaders properties. However, if you really want to change the request headers just for a particular request then you need to use the SendAsync method and pass it a HttpRequestMessage.
[Fact]
public async Task Post_a_form_and_change_some_headers()
{
var client = new HttpClient() { BaseAddress = _BaseAddress };
var values = new Dictionary<string, string>()
{
{"Id", "6"},
{"Name", "Skis"},
{"Price", "100"},
{"Category", "Sports"}
};
var content = new FormUrlEncodedContent(values);
var request = new HttpRequestMessage()
{
RequestUri = new Uri("devnull",UriKind.Relative),
Method = HttpMethod.Post,
Content = content
};
request.Headers.ExpectContinue = false;
request.Headers.Add("custom-header","a header value");
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
}