C#: HttpClient with POST parameters
Asked Answered
O

4

44

I use codes below to send POST request to a server:

string url = "http://myserver/method?param1=1&param2=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)?

Overalls answered 9/12, 2014 at 10:1 Comment(3)
It is sent as post, new HttpRequestMessage(HttpMethod.Post, url), by passing in HttpMethod.Post you are creating a POST request. What are param1 and param2?Unsightly
@BenRobinson Thanks. param1 & param2 are my parameters that I want to send them as POST parameters BUT query string.Overalls
@SandySands Thanks. It is in the Windows Phone Emulator and is hard to config it for Fiddler.Overalls
R
90

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

Rael answered 25/5, 2016 at 17:19 Comment(6)
That version does not work for me. The parameter received by the controller action is always null.Olivero
@Olivero feel free to post a new question linked to this one explaining your problem.Rael
and what about sending Get request by parameters?Richel
@HoseinAqajani I think it would be a great question to ask in a new post. Feel free to link it here as comment.Rael
List<KeyValuePair<string, string>> is more concise as query parameter keys aren't necessarily unique.Bohannon
While you are true (so here is an upvote), I dont like query parameter with duplicate. I dont only code in .net and since there is no spec about this, different server handle duplicate differently. Beside, duplicate can lead to HPP.Rael
P
0

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

Proof answered 15/2, 2023 at 21:16 Comment(0)
S
0

The answer as to whether the query is sent as a POST is, YES - the query is sent as a POST query.

If the server is an ASP.NET Web API and the query is not being seen by the server, then make sure that you decorate the parameter with [FromQuery] (sending it as a body should have either a [FromBody] of [FromForm])

Sibert answered 25/9, 2023 at 13:32 Comment(0)
C
-8

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&param2=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

Cemetery answered 9/12, 2014 at 13:45 Comment(3)
@JohnCroneh this isn't working anymore. Please accept the other answer below!Willette
@JohnCroneh please change the accepted answer to one that worksNerland
@R.McManaman Actually it's a good answer if you would go with creating an no known method type. It's missing some "using" to make sure that it disposes and a "make sure it's converted", but it follows the PostAsync wrapper implementation.Towland

© 2022 - 2024 — McMap. All rights reserved.