By Hooch


2010-10-25 14:05:58 8 Comments

Canonical
How can I make an HTTP request and send some data using the POST method?

I can do GET request but have no idea how to make a POST.

10 comments

@Evan Mulawski 2010-10-25 14:08:07

There are several ways to perform HTTP GET and POST requests:


Method A: HttpClient (Preferred)

This is a wrapper around HttpWebRequest. Compare with WebClient.

Available in: .NET Framework 4.5+, .NET Standard 1.1+, .NET Core 1.0+ .

Currently the preferred approach. Asynchronous. Portable version for other platforms available via NuGet.

using System.Net.Http;

Setup

It is recommended to instantiate one HttpClient for your application's lifetime and share it.

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: 3rd-Party Libraries

  • RestSharp

    Tried and tested library for interacting with REST APIs. Portable. Available via NuGet.

  • Flurl.Http

    Newer library sporting a fluent API and testing helpers. HttpClient under the hood. Portable. 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+

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+

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");
    }
    

@Lloyd 2011-03-25 17:38:28

How do you get the response from that?

@Evan Mulawski 2011-03-25 17:44:25

@Lloyd: HttpWebResponse response = (HttpWebResponse)HttpWReq.GetResponse();

@Lloyd 2011-03-25 18:52:25

after the newStream is closed?

@Evan Mulawski 2011-03-25 19:07:57

@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 2013-08-09 07:59:25

Why are you instantiating the ASCIIEncoding object instead of using the static System.Text.Encoding.ASCII?

@Gero 2013-08-09 11:04:19

Why do you even use ASCII? What if someone needs an xml with UTF-8?

@Hooch 2014-11-20 10:30:22

After 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. 2015-01-25 23:19:22

I hate to beat a dead horse but you should do response.Result.Content.ReadAsStringAsync()

@Evan Mulawski 2015-01-25 23:43:11

@DavidS. response should be a HttpResponseMessage - are you missing an await when calling PostAsync?

@Jaddie 2015-02-15 15:38:34

Just been having a look at using this and wondering what the reason for using a List with KeyValuePair was? This code could perhaps be simplified and made more readable by using a Dictionary instead and an object constructor could be used? I'll put an example of what I mean in an answer

@Jaddie 2015-02-15 15:46:09

I've instead after noticing its a versioned post, edited it in place, would be interested to see what people think about it, could expand it out back into add statements which would still be quite simple as just Add("thing1","hello"); for example

@Djeroen 2015-10-22 13:09:28

how would i send a header with your second (WebClient) post method

@Evan Mulawski 2015-10-22 13:11:05

@Djeroen: Use the Headers property of your WebClient instance. See the MSDN documentation for more info.

@Djeroen 2015-10-22 13:19:59

@EvanMulawski okay, thank you i found it and it works!

@itzick binder 2015-11-05 08:03:16

Is there a way to use a client but with several requests? I also need to change the client's URL between requests. So far I didn't succeed in doing it.

@Hiep 2015-11-18 13:27:10

why did you say WebRequest and WebClient are legacy? MSDN doesn't say that they are deprecated or anything. Am I missing something?

@Evan Mulawski 2015-11-18 14:47:20

@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.

@Ali.Rashidi 2016-06-26 07:39:44

stream? system.io.stream you mean? so confusing

@Fandi Susanto 2016-10-14 06:32:49

I realize this is quite out of topic, but can you please include in your answer how to connect with https.

@Evan Mulawski 2016-10-14 14:00:38

@FandiSusanto: The process is the same, just use https in the URL.

@Fandi Susanto 2016-10-15 12:23:52

It works. Thanks. It was so hard with WebClient. Looks like i don't need any ServicePointManager or X509Certificate for HttpClient. The only drawback is that i must call the async method with: System.Threading.Tasks.Task.Run(() => ThoseAsyncMethods())

@Greg A 2017-05-30 16:04:44

I 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 2017-05-30 17:42:48

@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 implements IDisposable does not mean you must put it in a using block.

@Greg A 2017-05-31 18:55:07

@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 2017-07-14 12:06:23

RestSharp seems to be dead. Simply dead.

@Hassan Tareq 2017-12-14 05:19:55

What if I use Singleton for Method A? I usually do it when using Retrofit in Android.

@hossein andarkhora 2018-02-13 13:03:30

thank's for your sulotion but i want send two level data to my api for example : { "applications": ["com.example.app"], "notification": { "title": "mytitle", "content": "mycontent" } }

@Vasya Milovidov 2018-03-22 11:17:54

@EvanMulawski, tell me please, how I can send data types like this: Dictionary<string, string>[] ?

@Sohi 2018-09-12 23:18:23

In Method A, what is the solution when you have data with one of the values itself as a key-value pair?

@Baruch Atta 2019-02-13 17:09:20

Could you provide a C# version of Method A? I am stuck on the "response = await" line. What is the C# equivalent?

@Evan Mulawski 2019-02-14 15:00:46

@BaruchAtta: That is C#. It should be in an async method. See stackoverflow.com/questions/14177891/…

@Wyck 2019-06-17 20:44:38

I wish this answer mentioned that it is possible to post raw byte[] content by substituting a ByteArrayContent for the example's FormUrlEncodedContent and to read raw byte[] content with response.Content.ReadAsByteArrayAsync().

@Douglas Ferreira 2019-08-01 14:51:06

What are advantages of HttpClient over HttpWebRequest and WebClient beyond asyncronism? Why the last two has become legacy?

@Evan Mulawski 2019-08-06 12:13:23

@DouglasFerreira HttpClient and WebClient are higher-level wrappers around HttpWebRequest. The real question is when to use HttpClient as opposed to WebClient (or vice versa); this is best described in stackoverflow.com/questions/20530152/….

@user8803505 2018-10-26 20:01:09

If you like fluent API you can use Tiny.RestClient. It's available at Nuget

var client = new TinyRestClient(new HttpClient(), "http://MyAPI.com/api");
// POST
var city = new City() { Name = "Paris", Country = "France" };
// With content
var response = await client.PostRequest("City", city)
                           .ExecuteAsync<bool>();

Hope that helps!

@Contango 2019-04-03 15:21:53

This solution uses nothing but standard .NET calls.

Tested:

  • In use in an enterprise WPF application. Uses async/await to avoid blocking the UI.
  • Compatible with .NET 4.5+.
  • Tested with no parameters (requires a "GET" behind the scenes).
  • Tested with parameters (requires a "POST" behind the scenes).
  • Tested with a standard web page such as Google.
  • Tested with an internal Java-based webservice.

Reference:

// Add a Reference to the assembly System.Web

Code:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;

private async Task<WebResponse> CallUri(string url, TimeSpan timeout)
{
    var uri = new Uri(url);
    NameValueCollection rawParameters = HttpUtility.ParseQueryString(uri.Query);
    var parameters = new Dictionary<string, string>();
    foreach (string p in rawParameters.Keys)
    {
        parameters[p] = rawParameters[p];
    }

    var client = new HttpClient { Timeout = timeout };
    HttpResponseMessage response;
    if (parameters.Count == 0)
    {
        response = await client.GetAsync(url);
    }
    else
    {
        var content = new FormUrlEncodedContent(parameters);
        string urlMinusParameters = uri.OriginalString.Split('?')[0]; // Parameters always follow the '?' symbol.
        response = await client.PostAsync(urlMinusParameters, content);
    }
    var responseString = await response.Content.ReadAsStringAsync();

    return new WebResponse(response.StatusCode, responseString);
}

private class WebResponse
{
    public WebResponse(HttpStatusCode httpStatusCode, string response)
    {
        this.HttpStatusCode = httpStatusCode;
        this.Response = response;
    }
    public HttpStatusCode HttpStatusCode { get; }
    public string Response { get; }
}

To call with no parameters (uses a "GET" behind the scenes):

 var timeout = TimeSpan.FromSeconds(300);
 WebResponse response = await this.CallUri("http://www.google.com/", timeout);
 if (response.HttpStatusCode == HttpStatusCode.OK)
 {
     Console.Write(response.Response); // Print HTML.
 }

To call with parameters (uses a "POST" behind the scenes):

 var timeout = TimeSpan.FromSeconds(300);
 WebResponse response = await this.CallUri("http://example.com/path/to/page?name=ferret&color=purple", timeout);
 if (response.HttpStatusCode == HttpStatusCode.OK)
 {
     Console.Write(response.Response); // Print HTML.
 }

@Adam 2018-10-10 18:45:27

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);

@Zeek2 2019-06-24 15:04:24

Useful, 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}";

@Nikolay Hristov 2018-04-16 11:33:00

You can use IEnterprise.Easy-HTTP since it has built in class parsing and query building:

await new RequestBuilder<ExampleObject>()
.SetHost("https://httpbin.org")
.SetContentType(ContentType.Application_Json)
.SetType(RequestType.Post)
.SetModelToSerialize(dto)
.Build()
.Execute();

I'm the author of the library so feel free to ask questions or check the code in github

@Hooch 2018-04-17 09:19:08

That is nice. But one more additional dependency for something that works really well in .NET implementation is not something that would be allowed in professional projects and is also unnecessary for even small hobby projects.

@Nikolay Hristov 2018-04-18 10:17:12

Hi Hooch, I do agree with your argument, but for me the efficiency in the nugget is the model parsing, since depending on your request you can easily parse models to form-data or to json.

@S4NNY1 2018-02-20 21:28:39

When using Windows.Web.Http namespace, for POST instead of FormUrlEncodedContent we write HttpFormUrlEncodedContent. Also the response is type of HttpResponseMessage. The rest is as Evan Mulawski wrote down.

@Pavlo Neyman 2011-11-11 09:28:26

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);
}

@user_v 2013-09-11 06:15:54

+1 For regular stuff POST it is great to have such short piece of code.

@Cameron Wilby 2013-11-09 02:45:59

Tim - 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 2014-01-03 22:09:10

I accepted your answer as good because it is much more simpler and clearer.

@Sindre 2014-01-17 19:52:01

I 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 2014-02-19 16:42:04

@Sindre You can add it to the post.

@ewwink 2014-09-11 02:54:43

I will avoid WebClient() because it has minimal option like no timeout option that make we wait 100 second if the site not available.

@Djeroen 2015-10-22 13:06:51

how would i send a header with this post request?

@Alan Moore 2016-07-10 17:29:54

What references do I need to add? Can this be included in the answer along with the necessary using statements?

@Bimal Poudel 2016-07-17 00:19:50

Further, you can send a bit complex array $_POST['user'] as: data["user[username]"] = "myUsername"; data["user[password]"] = "myPassword";

@Bimal Poudel 2016-07-17 00:22:38

@ewwink The timeout is discussed here: stackoverflow.com/questions/1789627/…

@Om Choudhary 2018-10-25 13:06:39

could you provide me the namespace for 'response' uses in 'var response = wb.UploadValues(url, "POST", data);'

@Shadow Wizard 2019-04-15 11:02:11

@OmChoudhary you mean the type? It's a byte array. byte[].

@Ivanzinho 2017-09-29 19:55:19

This is a complete working example of sending/receiving data in JSON format, I used VS2013 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);
        }
    }
}

@Ohad Cohen 2017-09-24 14:59:09

Simple (one-liner, no error checking, no wait for response) solution i've found so far

(new WebClient()).UploadStringAsync(new Uri(Address), dataString);‏

use with caution!

@Hooch 2017-09-25 11:24:53

That 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 2017-12-30 16:11:30

@Hooch others might be interested in this type of answers, even if it's not the best one.

@Extragorey 2019-05-09 03:58:35

Agreed, the only context in which this would be useful is code golfing and who golfs in C# ;)

@Otávio Décio 2010-10-25 14:07:31

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();
        }
    }
}

@AnKing 2014-07-30 14:48:53

For some reason it didnt work when i was sending large amount of data

Related Questions

Sponsored Content

34 Answered Questions

[SOLVED] PUT vs. POST in REST

  • 2009-03-10 14:25:20
  • alex
  • 2217618 View
  • 5139 Score
  • 34 Answer
  • Tags:   http rest post put

26 Answered Questions

[SOLVED] How do I enumerate an enum in C#?

29 Answered Questions

[SOLVED] JavaScript post request like a form submit

14 Answered Questions

[SOLVED] HTTP test server accepting GET/POST requests

  • 2011-04-20 04:17:11
  • John Twigg
  • 332606 View
  • 411 Score
  • 14 Answer
  • Tags:   http post

19 Answered Questions

[SOLVED] Proper use of the IDisposable interface

19 Answered Questions

[SOLVED] How is an HTTP POST request made in node.js?

11 Answered Questions

22 Answered Questions

[SOLVED] How can I post data as form data instead of a request payload?

8 Answered Questions

[SOLVED] How are parameters sent in an HTTP POST request?

8 Answered Questions

[SOLVED] Are HTTPS headers encrypted?

Sponsored Content