[c#] How to make an HTTP POST web request

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

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

This question is related to c# .net post httpwebrequest httprequest

The answer is


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

You can also use Postman App for Windows, Linux or OSX. It is a complete web app & service test environment that involve all the request methods. You can find the latest version here.


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

POST request in itself means sending information in the body. I found a fairly simple way to do this. Use Postman by Google, which allows you to specify the content-type(a header field) as application/json and then provide name-value pairs as parameters. Just use your url in the place of theirs.

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

Yet another way of doing it:

using (HttpClient httpClient = new HttpClient())
using (MultipartFormDataContent form = new MultipartFormDataContent())
{
    form.Add(new StringContent(param1), "param1");
    form.Add(new StringContent(param2), "param2");
    using (HttpResponseMessage response = await httpClient.PostAsync(url, form))
    {
        response.EnsureSuccessStatusCode();
        string res = await response.Content.ReadAsStringAsync();
        return res;
    }
}

This way you can easily post a stream.


If you like a 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>();

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

Here's what i use in .NET 4.8 to make a HTTP POST request. With this code one can send multiple POST requests at a time Asynchronously. At the end of each request an event is raised. And also at the end of all request another event is raised.

The one bellow is the core class:

Imports System.ComponentModel
Imports System.Text.RegularExpressions
Imports System.Timers
Imports System.Windows.Forms
Imports AeonLabs
Imports AeonLabs.Environment
Imports Newtonsoft.Json

Public Class HttpDataCore
    Public Property url As String
    Public Property state As New environmentVarsCore
    Public Property errorMessage As String = ""
    Public Property statusMessage As String
    Public Property threadCount As Integer = 25
    Public Property numberOfRetryAttempts = 5
    Public Property queue As List(Of _queue_data_struct)
    Public Property queueBWorker As Integer() ' has the size of threadCount
    Public Property queueLock As New Object
    Public Property retryAttempts As New _retry_attempts
    Public Property dataStatistics As List(Of _data_statistics)
    Public Property loadingCounter As Integer
    Public Property CompletionPercentage As Integer ' value range 0-100
    Public Property IsBusy As Boolean

    Public Structure _queue_data_struct
        Dim vars As Dictionary(Of String, String)
        Dim filenameOrSavePath As String                  ' full address file name or full adress folder path
        Dim misc As Dictionary(Of String, String)
        Dim status As Integer                             ' -1 - completed; 0- not sent yet; 1-already sent / processing 
    End Structure
    Public Structure _retry_attempts
        Dim counter As Integer
        Dim pattern As Integer
        Dim previousPattern As Integer
        Dim errorMessage As String
    End Structure
    Public Structure _data_statistics
        Dim filesize As Double
        Dim bytesSentReceived As Double
        Dim speed As Double
    End Structure

    Public WithEvents RestartQueueTimer As New Timers.Timer
    Public bwDataRequest() As BackgroundWorker

    Public Event requestCompleted(sender As Object, requestData As String) 'TODO add misc vars

    Private sendToQueue As Boolean
    Public Sub New(ByVal Optional _state As environmentVarsCore = Nothing, ByVal Optional _url As String = "")
        queue = New List(Of _queue_data_struct)
        dataStatistics = New List(Of _data_statistics)
        loadingCounter = 0
        sendToQueue = False
        If _state IsNot Nothing AndAlso _url.Equals("") Then
            url = _state.ServerBaseAddr & _state.ApiServerAddrPath
        ElseIf Not _url.Equals("") Then
            url = _url
        Else
            Throw New System.Exception("Initialization err: state and url cannot be both null at same time")
        End If

        If _state IsNot Nothing Then
            state = _state
        End If

    End Sub
    Public Sub loadQueue(ByVal vars As Dictionary(Of String, String), ByVal Optional misc As Dictionary(Of String, String) = Nothing, ByVal Optional filenameOrSavePath As String = Nothing)
        Dim queueItem As New _queue_data_struct
        queueItem.vars = New Dictionary(Of String, String)
        queueItem.misc = New Dictionary(Of String, String)

        queueItem.vars = vars
        queueItem.status = 0
        queueItem.misc = misc
        queueItem.filenameOrSavePath = filenameOrSavePath
        queue.Add(queueItem)
    End Sub

    Public Sub clearQueue()
        loadingCounter = 0
        queue = New List(Of _queue_data_struct)
    End Sub
    Public Sub startRequest()
        If bwDataRequest(0) Is Nothing Then
            Throw New Exception("You need to call initialze first")
            Exit Sub
        End If

        'startSendQueue()
        IsBusy = True

        AddHandler RestartQueueTimer.Elapsed, New ElapsedEventHandler(AddressOf QueueTimerTick)
        With RestartQueueTimer
            .Enabled = True
            .Interval = 500
            .Start()
        End With
    End Sub

    Private Sub QueueTimerTick(ByVal sender As Object, ByVal e As ElapsedEventArgs)
        If QueuesToComplete(queue).Equals(0) And QueuesToSend(queue).Equals(0) Then
            RestartQueueTimer.Stop()
            queue = New List(Of _queue_data_struct)
            RaiseEvent requestCompleted(Me, Nothing)
            IsBusy = False
            Exit Sub
        End If

        If retryAttempts.counter >= numberOfRetryAttempts Then 'ToDo a retry number of attempts before quits
            Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
            Dim MsgBox As messageBoxForm
            MsgBox = New messageBoxForm(retryAttempts.errorMessage & ". " & My.Resources.strings.tryAgain & " ?", My.Resources.strings.question, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
            If MsgBox.ShowDialog() = DialogResult.Yes Then
                Dim retry As _retry_attempts
                With retry
                    .counter = 0
                    .previousPattern = -1
                    .pattern = 0
                    .errorMessage = ""
                End With
                retryAttempts = retry
                startSendQueue()
            Else
                RestartQueueTimer.Stop()
                queue = New List(Of _queue_data_struct)
                RaiseEvent requestCompleted(Me, Nothing)
                IsBusy = False
                Exit Sub
            End If
            Exit Sub
        ElseIf Not sendToQueue And QueuesToSend(queue) > 0 Then
            startSendQueue()
        End If
    End Sub

    Private Sub startSendQueue()
        sendToQueue = True
        While QueuesToSend(queue) > 0
            For shtIndex = 0 To threadCount
                For i = 0 To queue.Count - 1
                    If Not bwDataRequest(shtIndex).IsBusy Then
                        SyncLock queueLock
                            If queue.ElementAt(i).status.Equals(0) Then
                                Dim data As New _queue_data_struct
                                data.vars = queue.ElementAt(i).vars
                                data.status = 1
                                data.misc = queue.ElementAt(i).misc
                                data.filenameOrSavePath = queue.ElementAt(i).filenameOrSavePath
                                queue(i) = data
                                queueBWorker(shtIndex) = i
                                dataStatistics(shtIndex) = (New _data_statistics)

                                bwDataRequest(shtIndex).RunWorkerAsync(queue(i))
                                Threading.Thread.Sleep(50)
                            End If
                        End SyncLock
                    End If
                Next i
            Next shtIndex
        End While
        sendToQueue = False
    End Sub

    Public Function QueuesToSend(queue As List(Of _queue_data_struct)) As Integer
        Dim counter As Integer = 0
        For i = 0 To queue.Count - 1
            If queue(i).status.Equals(0) Then
                counter += 1
            End If
        Next i
        Return counter
    End Function
    Public Function QueuesToComplete(queue As List(Of _queue_data_struct)) As Integer
        Dim counter As Integer = 0
        For i = 0 To queue.Count - 1
            If queue(i).status.Equals(1) Then
                counter += 1
            End If
        Next i
        Return counter
    End Function
    Public Function QueuesMultiHash(queue As List(Of _queue_data_struct)) As Integer
        Dim counter As Integer = 0
        For i = 0 To queue.Count - 1
            If queue(i).status.Equals(1) Then
                counter += i
            End If
        Next i
        Return counter
    End Function

    Public Function IsBase64String(ByVal s As String) As Boolean
        s = s.Trim()
        Return (s.Length Mod 4 = 0) AndAlso Regex.IsMatch(s, "^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None)
    End Function

    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Public Function ConvertDataToArray(key As String, fields As String(), response As String) As Dictionary(Of String, List(Of String))
        If GetMessage(response).Equals("1001") Then
            Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
            errorMessage = "{'error':true,'message':'" & My.Resources.strings.errorNoRecordsFound & "'}"
            Return Nothing
        End If
        Try
            Dim jsonResult = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(response)
            If jsonResult.ContainsKey(key) Then
                If Not jsonResult.Item(key).item(0).Count.Equals(fields.Length) Then
                    Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
                    errorMessage = "{'error':true,'message':'" & My.Resources.strings.JsonFieldsMismatch & ". table(" & key & "'}"
                    Return Nothing
                Else
                    Dim results = New Dictionary(Of String, List(Of String))
                    For k = 0 To fields.Length - 1
                        Dim fieldValues As List(Of String) = New List(Of String)
                        For i = 0 To jsonResult.Item(key).Count - 1
                            fieldValues.Add(jsonResult.Item(key).item(i).item(k).ToString)
                        Next i
                        results.Add(fields(k), fieldValues)

                    Next k
                    Return results
                End If
            Else
                Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
                errorMessage = "{'error':true,'message':'" & My.Resources.strings.JsonkeyNotFound & " (" & key & "'}"
                Return Nothing
            End If
        Catch ex As Exception
            errorMessage = "{'error':true,'message':'" & ex.ToString & "'}"
            errorMessage = ex.ToString
            Return Nothing
        End Try
    End Function
End Class

the AeonLabs.Envoriment is a class with a collection or fields and properties.

And the one bellow is for making a POST request:

Imports System.ComponentModel
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Web
Imports System.Web.Script.Serialization
Imports System.Windows.Forms
Imports AeonLabs.Environment
Imports AeonLabs.Security

Public Class HttpDataPostData
    Inherits HttpDataCore

    Public Event updateProgress(sender As Object, misc As Dictionary(Of String, String))
    Public Event dataArrived(sender As Object, requestData As String, misc As Dictionary(Of String, String))

    Public Sub New(ByVal Optional _state As environmentVarsCore = Nothing, ByVal Optional _url As String = "")
        MyBase.New(_state, _url)
    End Sub
    Public Sub initialize(ByVal Optional _threadCount As Integer = 0)
        If Not _threadCount.Equals(0) Then
            threadCount = _threadCount
        End If

        ReDim bwDataRequest(threadCount)
        ReDim queueBWorker(threadCount)

        For shtIndex = 0 To threadCount
            dataStatistics.Add(New _data_statistics)

            bwDataRequest(shtIndex) = New System.ComponentModel.BackgroundWorker
            bwDataRequest(shtIndex).WorkerReportsProgress = True
            bwDataRequest(shtIndex).WorkerSupportsCancellation = True

            AddHandler bwDataRequest(shtIndex).DoWork, AddressOf bwDataRequest_DoWork
            AddHandler bwDataRequest(shtIndex).RunWorkerCompleted, AddressOf bwDataRequest_RunWorkerCompleted
        Next shtIndex
        Dim retry As _retry_attempts
        With retry
            .counter = 0
            .previousPattern = -1
            .pattern = 0
            .errorMessage = ""
        End With
        retryAttempts = retry
    End Sub

    Private Sub bwDataRequest_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)

        ' Find out the Index of the bWorker that called this DoWork (could be cleaner, I know)
        Dim Y As Integer
        Dim Index As Integer = Nothing
        For Y = 0 To UBound(bwDataRequest)
            If sender.Equals(bwDataRequest(Y)) Then
                Index = Y
                Exit For
            End If
        Next Y

        Dim queue As _queue_data_struct
        queue = e.Argument

        Dim vars As New Dictionary(Of String, String)
        vars = queue.vars

        'TODO translation need to be local
        If Not System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() Then
            Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
            e.Result = "{'error':true,'message':'" & My.Resources.strings.errorNoNetwork & "'}"
            Exit Sub
        End If
        If vars Is Nothing Then
            e.Result = "{'error':true,'message':'missconfiguration vars'}"
            Exit Sub
        End If

        If Not vars.ContainsKey("id") Then
            vars.Add("id", state.userId)
        End If
        If Not vars.ContainsKey("pid") Then
            Dim appId As New FingerPrint
            vars.Add("pid", appId.Value)
        End If
        If Not vars.ContainsKey("language") Then
            vars.Add("language", state.currentLang)
        End If
        If Not vars.ContainsKey("origin") Then
            vars.Add("origin", state.softwareAccessMode)
        End If

        Dim serializer As New JavaScriptSerializer()
        Dim json As String = serializer.Serialize(vars)
        Dim encryption As New AesCipher(state)
        Dim encrypted As String = HttpUtility.UrlEncode(encryption.encrypt(json))
        Dim PostData = "origin=" & state.softwareAccessMode & "&data=" & encrypted
        Dim request As WebRequest = WebRequest.Create(url)
        Dim responseFromServer As String = ""
        Dim decrypted As String = ""

        request.Method = "POST"
        Dim byteArray As Byte() = Encoding.UTF8.GetBytes(PostData)
        request.ContentType = "application/x-www-form-urlencoded"
        request.Headers.Add("Authorization", state.ApiHttpHeaderToken & "-" & state.softwareAccessMode)
        request.ContentLength = byteArray.Length
        Try
            Dim dataStream As Stream = request.GetRequestStream()
            dataStream.Write(byteArray, 0, byteArray.Length)
            dataStream.Close()
            Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
            dataStream = response.GetResponseStream()
            Dim reader As New StreamReader(dataStream)
            responseFromServer = reader.ReadToEnd()
            reader.Close()
            dataStream.Close()
            response.Close()

            If response.StatusCode = HttpStatusCode.Accepted Or response.StatusCode = 200 Then
                If IsBase64String(responseFromServer) And Not responseFromServer.Equals("") Then
                    decrypted = encryption.decrypt((responseFromServer)).Replace("\'", "'")
                Else
                    Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
                    decrypted = "{'error':true,'encrypted':false,'message':'" & My.Resources.strings.contactingCommServer & " |" & responseFromServer & "|'}"
                End If
            Else
                Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
                decrypted = "{'error':true,'message':'" & My.Resources.strings.contactingCommServer & " (" & response.StatusCode & ")', 'statuscode':'" & response.StatusCode & "'}"
            End If
        Catch ex As Exception
            Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
            decrypted = "{'error':true,'message':'" & My.Resources.strings.contactingCommServer & " (" & ex.Message.ToString.Replace("'", "\'") & ")'}"
        End Try

        e.Result = decrypted.Replace("\'", "'")
    End Sub

    Private Sub bwDataRequest_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
        ' Find out the Index of the bWorker that called this DoWork (could be cleaner, I know)
        Dim Y As Integer
        Dim Index As Integer = Nothing
        Dim data As New _queue_data_struct

        For Y = 0 To UBound(bwDataRequest)
            If sender.Equals(bwDataRequest(Y)) Then
                Index = Y
                Exit For
            End If
        Next Y

        If IsResponseOk(e.Result, "statuscode") Then
            data = New _queue_data_struct
            data = queue(queueBWorker(Index))
            data.status = 0 're queue the file
            SyncLock queueLock
                queue(queueBWorker(Index)) = data
            End SyncLock
            Dim errorMsg As String = GetMessage(e.Result)
            Dim retry As _retry_attempts
            With retry
                .counter = retryAttempts.counter
                .previousPattern = retryAttempts.previousPattern
                .pattern = retryAttempts.pattern
                .errorMessage = retryAttempts.errorMessage
            End With
            retry.errorMessage = If(retryAttempts.errorMessage.IndexOf(errorMsg) > -1, retryAttempts.errorMessage, retryAttempts.errorMessage & System.Environment.NewLine & errorMsg)

            retry.pattern = QueuesMultiHash(queue)
            If retry.previousPattern.Equals(retry.pattern) Then
                retry.counter += 1
            Else
                retry.counter = 1
                retry.previousPattern = retryAttempts.pattern
            End If

            retryAttempts = retry
            Exit Sub
        End If

        data = New _queue_data_struct
        data = queue(queueBWorker(Index))
        data.status = -1 'completed sucessfully status
        SyncLock queueLock
            queue(queueBWorker(Index)) = data
        End SyncLock

        loadingCounter += 1
        CompletionPercentage = (loadingCounter / queue.Count) * 100
        statusMessage = "Loading data from the cloud ..."
        RaiseEvent updateProgress(Me, queue(queueBWorker(Index)).misc)
        RaiseEvent dataArrived(Me, e.Result, queue(queueBWorker(Index)).misc)
    End Sub
End Class

The Aoenlabs.Security is a class for sending POST data encrypted using standard encryption algorithms


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.


In .net core you can make post-call with following code, here I added some extra features to this code so can make your code work behind a proxy and with network credentials if any, also here I mention that you can change the encoding of your message. I hope this explains all and help you in coding.

HttpClient client = GetHttpClient(_config);

        if (headers != null)
        {
            foreach (var header in headers)
            {
                client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
            }
        }

        client.BaseAddress = new Uri(baseAddress);

        Encoding encoding = Encoding.UTF8;


        var result = await client.PostAsync(url, new StringContent(body, encoding, "application/json")).ConfigureAwait(false);
        if (result.IsSuccessStatusCode)
        {
            return new RequestResponse { severity = "Success", httpResponse = result.Content.ReadAsStringAsync().Result, StatusCode = result.StatusCode };
        }
        else
        {
            return new RequestResponse { severity = "failure", httpResponse = result.Content.ReadAsStringAsync().Result, StatusCode = result.StatusCode };
        }


 public HttpClient GetHttpClient(IConfiguration _config)
        {
            bool ProxyEnable = Convert.ToBoolean(_config["GlobalSettings:ProxyEnable"]);

            HttpClient client = null;
            if (!ProxyEnable)
            {
                client = new HttpClient();
            }
            else
            {
                string ProxyURL = _config["GlobalSettings:ProxyURL"];
                string ProxyUserName = _config["GlobalSettings:ProxyUserName"];
                string ProxyPassword = _config["GlobalSettings:ProxyPassword"];
                string[] ExceptionURL = _config["GlobalSettings:ExceptionURL"].Split(';');
                bool BypassProxyOnLocal = Convert.ToBoolean(_config["GlobalSettings:BypassProxyOnLocal"]);
                bool UseDefaultCredentials = Convert.ToBoolean(_config["GlobalSettings:UseDefaultCredentials"]);

                WebProxy proxy = new WebProxy
                {
                    Address = new Uri(ProxyURL),
                    BypassProxyOnLocal = BypassProxyOnLocal,
                    UseDefaultCredentials = UseDefaultCredentials,
                    BypassList = ExceptionURL,
                    Credentials = new NetworkCredential(ProxyUserName, ProxyPassword)

                };

                HttpClientHandler handler = new HttpClientHandler { Proxy = proxy };
                client = new HttpClient(handler,true);
            }
            return client;
        }

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

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!


Why is this not totally trivial? Doing the request is not and especially not dealing with the results and seems like there are some .NET bugs involved as well - see Bug in HttpClient.GetAsync should throw WebException, not TaskCanceledException

I ended up with this code:

static async Task<(bool Success, WebExceptionStatus WebExceptionStatus, HttpStatusCode? HttpStatusCode, string ResponseAsString)> HttpRequestAsync(HttpClient httpClient, string url, string postBuffer = null, CancellationTokenSource cts = null) {
    try {
        HttpResponseMessage resp = null;

        if (postBuffer is null) {
            resp = cts is null ? await httpClient.GetAsync(url) : await httpClient.GetAsync(url, cts.Token);

        } else {
            using (var httpContent = new StringContent(postBuffer)) {
                resp = cts is null ? await httpClient.PostAsync(url, httpContent) : await httpClient.PostAsync(url, httpContent, cts.Token);
            }
        }

        var respString = await resp.Content.ReadAsStringAsync();
        return (resp.IsSuccessStatusCode, WebExceptionStatus.Success, resp.StatusCode, respString);

    } catch (WebException ex) {
        WebExceptionStatus status = ex.Status;
        if (status == WebExceptionStatus.ProtocolError) {
            // Get HttpWebResponse so that you can check the HTTP status code.
            using (HttpWebResponse httpResponse = (HttpWebResponse)ex.Response) {
                return (false, status, httpResponse.StatusCode, httpResponse.StatusDescription);
            }
        } else {
            return (false, status, null, ex.ToString()); 
        }

    } catch (TaskCanceledException ex) {
        if (cts is object && ex.CancellationToken == cts.Token) {
            // a real cancellation, triggered by the caller
            return (false, WebExceptionStatus.RequestCanceled, null, ex.ToString());
        } else {
            // a web request timeout (possibly other things!?)
            return (false, WebExceptionStatus.Timeout, null, ex.ToString());
        }

    } catch (Exception ex) {
        return (false, WebExceptionStatus.UnknownError, null, ex.ToString());
    }
}

This will do a GET or POST depends if postBuffer is null or not

if Success is true the response will then be in ResponseAsString

if Success is false you can check WebExceptionStatus, HttpStatusCode and ResponseAsString to try to see what went wrong.


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

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to post

How to post query parameters with Axios? How can I add raw data body to an axios request? HTTP POST with Json on Body - Flutter/Dart How do I POST XML data to a webservice with Postman? How to set header and options in axios? Redirecting to a page after submitting form in HTML How to post raw body data with curl? How do I make a https post in Node Js without any third party module? How to convert an object to JSON correctly in Angular 2 with TypeScript Postman: How to make multiple requests at the same time

Examples related to httpwebrequest

C# HttpWebRequest The underlying connection was closed: An unexpected error occurred on a send How to properly make a http web GET request Send JSON via POST in C# and Receive the JSON returned? How to create JSON post to api using C# Use C# HttpWebRequest to send json to web service Post form data using HttpWebRequest HttpWebRequest-The remote server returned an error: (400) Bad Request Get host domain from URL? How to ignore the certificate check when ssl Receiving JSON data back from HTTP request

Examples related to httprequest

Http post and get request in angular 6 Postman: How to make multiple requests at the same time Adding header to all request with Retrofit 2 Understanding Chrome network log "Stalled" state Why is this HTTP request not working on AWS Lambda? Simulate a specific CURL in PostMan HTTP Request in Swift with POST method What are all the possible values for HTTP "Content-Type" header? How to get host name with port from a http or https request Why I get 411 Length required error?