How to make an HTTP POST web request
Solution 1
There are several ways to perform HTTP GET
and POST
requests:
Method A: HttpClient (Preferred)
Available in: .NET Framework 4.5+
, .NET Standard 1.1+
, .NET Core 1.0+
.
It is currently the preferred approach, and is asynchronous and high performance. Use the built-in version in most cases, but for very old platforms there is a NuGet package.
using System.Net.Http;
Setup
It is recommended to instantiate one HttpClient
for your application's lifetime and share it unless you have a specific reason not to.
private static readonly HttpClient client = new HttpClient();
See HttpClientFactory
for a dependency injection solution.
-
POST
var values = new Dictionary<string, string> { { "thing1", "hello" }, { "thing2", "world" } }; var content = new FormUrlEncodedContent(values); var response = await client.PostAsync("http://www.example.com/recepticle.aspx", content); var responseString = await response.Content.ReadAsStringAsync();
-
GET
var responseString = await client.GetStringAsync("http://www.example.com/recepticle.aspx");
Method B: Third-Party Libraries
-
POST
var client = new RestClient("http://example.com"); // client.Authenticator = new HttpBasicAuthenticator(username, password); var request = new RestRequest("resource/{id}"); request.AddParameter("thing1", "Hello"); request.AddParameter("thing2", "world"); request.AddHeader("header", "value"); request.AddFile("file", path); var response = client.Post(request); var content = response.Content; // Raw content as string var response2 = client.Post<Person>(request); var name = response2.Data.Name;
It is a newer library sporting a fluent API, testing helpers, uses HttpClient under the hood, and is portable. It is available via NuGet.
using Flurl.Http;
-
POST
var responseString = await "http://www.example.com/recepticle.aspx" .PostUrlEncodedAsync(new { thing1 = "hello", thing2 = "world" }) .ReceiveString();
-
GET
var responseString = await "http://www.example.com/recepticle.aspx" .GetStringAsync();
Method C: HttpWebRequest (not recommended for new work)
Available in: .NET Framework 1.1+
, .NET Standard 2.0+
, .NET Core 1.0+
. In .NET Core, it is mostly for compatibility -- it wraps HttpClient
, is less performant, and won't get new features.
using System.Net;
using System.Text; // For class Encoding
using System.IO; // For StreamReader
-
POST
var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx"); var postData = "thing1=" + Uri.EscapeDataString("hello"); postData += "&thing2=" + Uri.EscapeDataString("world"); var data = Encoding.ASCII.GetBytes(postData); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = data.Length; using (var stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
-
GET
var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx"); var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Method D: WebClient (Not recommended for new work)
This is a wrapper around HttpWebRequest
. Compare with HttpClient
.
Available in: .NET Framework 1.1+
, NET Standard 2.0+
, .NET Core 2.0+
.
In some circumstances (.NET Framework 4.5-4.8), if you need to do a http request synchronously, WebClient
can still be used.
using System.Net;
using System.Collections.Specialized;
-
POST
using (var client = new WebClient()) { var values = new NameValueCollection(); values["thing1"] = "hello"; values["thing2"] = "world"; var response = client.UploadValues("http://www.example.com/recepticle.aspx", values); var responseString = Encoding.Default.GetString(response); }
-
GET
using (var client = new WebClient()) { var responseString = client.DownloadString("http://www.example.com/recepticle.aspx"); }
Solution 2
Simple GET request
using System.Net;
...
using (var wb = new WebClient())
{
var response = wb.DownloadString(url);
}
Simple POST request
using System.Net;
using System.Collections.Specialized;
...
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["username"] = "myUser";
data["password"] = "myPassword";
var response = wb.UploadValues(url, "POST", data);
string responseInString = Encoding.UTF8.GetString(response);
}
Solution 3
MSDN has a sample.
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestPostExample
{
public static void Main()
{
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("http://www.contoso.com/PostAccepter.aspx");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
}
}
}
Solution 4
This is a complete working example of sending/receiving data in JSON format, I used Visual Studio 2013 Express Edition:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
namespace ConsoleApplication1
{
class Customer
{
public string Name { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
}
public class Program
{
private static readonly HttpClient _Client = new HttpClient();
private static JavaScriptSerializer _Serializer = new JavaScriptSerializer();
static void Main(string[] args)
{
Run().Wait();
}
static async Task Run()
{
string url = "http://www.example.com/api/Customer";
Customer cust = new Customer() { Name = "Example Customer", Address = "Some example address", Phone = "Some phone number" };
var json = _Serializer.Serialize(cust);
var response = await Request(HttpMethod.Post, url, json, new Dictionary<string, string>());
string responseText = await response.Content.ReadAsStringAsync();
List<YourCustomClassModel> serializedResult = _Serializer.Deserialize<List<YourCustomClassModel>>(responseText);
Console.WriteLine(responseText);
Console.ReadLine();
}
/// <summary>
/// Makes an async HTTP Request
/// </summary>
/// <param name="pMethod">Those methods you know: GET, POST, HEAD, etc...</param>
/// <param name="pUrl">Very predictable...</param>
/// <param name="pJsonContent">String data to POST on the server</param>
/// <param name="pHeaders">If you use some kind of Authorization you should use this</param>
/// <returns></returns>
static async Task<HttpResponseMessage> Request(HttpMethod pMethod, string pUrl, string pJsonContent, Dictionary<string, string> pHeaders)
{
var httpRequestMessage = new HttpRequestMessage();
httpRequestMessage.Method = pMethod;
httpRequestMessage.RequestUri = new Uri(pUrl);
foreach (var head in pHeaders)
{
httpRequestMessage.Headers.Add(head.Key, head.Value);
}
switch (pMethod.Method)
{
case "POST":
HttpContent httpContent = new StringContent(pJsonContent, Encoding.UTF8, "application/json");
httpRequestMessage.Content = httpContent;
break;
}
return await _Client.SendAsync(httpRequestMessage);
}
}
}
Solution 5
There are some really good answers on here. Let me post a different way to set your headers with the WebClient(). I will also show you how to set an API key.
var client = new WebClient();
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + passWord));
client.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";
//If you have your data stored in an object serialize it into json to pass to the webclient with Newtonsoft's JsonConvert
var encodedJson = JsonConvert.SerializeObject(newAccount);
client.Headers.Add($"x-api-key:{ApiKey}");
client.Headers.Add("Content-Type:application/json");
try
{
var response = client.UploadString($"{apiurl}", encodedJson);
//if you have a model to deserialize the json into Newtonsoft will help bind the data to the model, this is an extremely useful trick for GET calls when you have a lot of data, you can strongly type a model and dump it into an instance of that class.
Response response1 = JsonConvert.DeserializeObject<Response>(response);
Hooch
Updated on April 16, 2022Comments
-
Hooch about 2 years
Canonical
How can I make an HTTP request and send some data using thePOST
method?I can do a
GET
request, but I have no idea of how to make aPOST
request. -
Lloyd about 13 yearsHow do you get the response from that?
-
Evan Mulawski about 13 years@Lloyd:
HttpWebResponse response = (HttpWebResponse)HttpWReq.GetResponse();
-
Lloyd about 13 yearsafter the newStream is closed?
-
Evan Mulawski about 13 years@Lloyd: If you are posting data to the stream (using the last three lines) it would make sense to check the response beforehand.
-
Mathias Lykkegaard Lorenzen over 10 yearsWhy are you instantiating the ASCIIEncoding object instead of using the static
System.Text.Encoding.ASCII
? -
Gero over 10 yearsWhy do you even use ASCII? What if someone needs an xml with UTF-8?
-
user_v over 10 years+1 For regular stuff POST it is great to have such short piece of code.
-
Cameron Wilby over 10 yearsTim - If you right click the literal that can't be resolved, you will find a Resolve context menu, which contains actions to add the Using statements for you. If the Resolve context menu doesn't show up, it means you need to add references first.
-
Hooch over 10 yearsI accepted your answer as good because it is much more simpler and clearer.
-
Sindre over 10 yearsI would like to add that the response variable for the POST request is a byte array. In order to get the string response you just do Encoding.ASCII.GetString(response); (using System.Text)
-
Hooch about 10 years@Sindre You can add it to the post.
-
AnKing almost 10 yearsFor some reason it didnt work when i was sending large amount of data
-
Hooch over 9 yearsAfter so long time. I switched accepted answer to yours. As it is so much more detailed and I like that you shown old, obsolete methods.
-
David S. over 9 yearsI hate to beat a dead horse but you should do
response.Result.Content.ReadAsStringAsync()
-
Evan Mulawski over 9 years@DavidS.
response
should be aHttpResponseMessage
- are you missing anawait
when callingPostAsync
? -
Hiep over 8 yearswhy did you say WebRequest and WebClient are legacy? MSDN doesn't say that they are deprecated or anything. Am I missing something?
-
Evan Mulawski over 8 years@Hiep: They are not deprecated, there are just newer (and is most cases, better and more flexible) ways of making web requests. In my opinion, for simple, non-critical operations, the old ways are just fine - but it's up to you and whatever you are most comfortable with.
-
Bimal Poudel almost 8 yearsFurther, you can send a bit complex array $_POST['user'] as: data["user[username]"] = "myUsername"; data["user[password]"] = "myPassword";
-
Greg A almost 7 yearsI know you said the preferred method is to instantiate a private readonly HttpClient but I think it is cleaner (and safer) to do a using statement instead.
using (var client = new HttpClient()) { }
-
Evan Mulawski almost 7 years@GregA: It's not just me. The developers of
HttpClient
recommend one instantiation per application. In reality, it may be necessary to instantiate more, depending on what your application does. Just because it implementsIDisposable
does not mean you must put it in ausing
block. -
Greg A almost 7 years@EvanMulawski Evan, in my application I am using dependency injection in a web api. In my case i believe taking advantage of the
using
block is the correct way to go. -
hellboy almost 7 years
RestSharp
seems to be dead. Simply dead. -
Hooch over 6 yearsThat is quite bad. I don't recommend it as there is no error handling of any kind and debugging it is pain. Additionally there already is great answer to this question.
-
Mitulát báti over 6 years@Hooch others might be interested in this type of answers, even if it's not the best one.
-
Extragorey almost 5 yearsAgreed, the only context in which this would be useful is code golfing and who golfs in C# ;)
-
Wyck almost 5 yearsI wish this answer mentioned that it is possible to post raw
byte[]
content by substituting aByteArrayContent
for the example'sFormUrlEncodedContent
and to read rawbyte[]
content withresponse.Content.ReadAsByteArrayAsync()
. -
Zeek2 almost 5 yearsUseful, thanks. BTW It looks like the above technique for setting header-properties also works for the older (deprecated?), HttpWebRequest approach. e.g. myReq.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";
-
Douglas Ferreira over 4 yearsWhat are advantages of HttpClient over HttpWebRequest and WebClient beyond asyncronism? Why the last two has become legacy?
-
Evan Mulawski over 4 years@DouglasFerreira
HttpClient
andWebClient
are higher-level wrappers aroundHttpWebRequest
. The real question is when to useHttpClient
as opposed toWebClient
(or vice versa); this is best described in stackoverflow.com/questions/20530152/…. -
rkachach about 4 yearsShort and simple solution, I like it :)
-
elnaz jangi almost 4 yearsThank you very much for your complete and useful answer. I learned a whole new way by reading it, because I've just started learning C # programming.
-
Ohad Cohen almost 4 yearsI wrote this answer looking for http based logging solution, I guess some other people might find it usefull similarly.
-
Epirocks over 3 years@AnKing there is scope for that to be server limits rather than the client sending it.
-
Danimal111 over 3 yearsI have been working on this for too long. Soooo far from trivial... in Java I need about 6-8 lines.
-
kofifus over 3 yearsseems like things are getting better see devblogs.microsoft.com/dotnet/net-5-new-networking-improvements
-
T.Todua over 2 years
-
Rony Tesler about 2 yearsFor method A - adding headers: client.DefaultRequestHeaders.Add("name", "value");
-
bbsimonbb almost 2 yearsHttpClient has properties like
BaseAddress
and handy methods likeCancelPendingRequests()
. "Instantiat[ing] one HttpClient for your application's lifetime" would be a very brave thing to do. I believe the intention is to create 1 HttpClient per use case or group of use cases attacking a same origin, in a singleton scoped service class or something like that. So there's a whole bunch of complexity you didn't ask for and likely don't need. 3 cheers for OO. -
obesechicken13 almost 2 yearsHttpClient is a bish to test since it has no interface stackoverflow.com/questions/36425008/… You need all kinds of workarounds to write a unit test for it, just a consideration
-
Evan Mulawski almost 2 years@obesechicken13 You would typically mock the underlying handler instead of HttpClient itself (see
Moq.Contrib.HttpClient
package).