HttpClient GetAsync, PostAsync, SendAsync in C#

10 Comments

HttpClient is a library in the Microsoft .NET framework 4+ that is used for GET and POST requests. Let’s go through a simple example of using HttpClient to GET and POST JSON from a web application.

First, we will create our client application. We will create a new console app in Visual Studio:

Add the System.Net.Http namespace. We will pull down JSON data from a REST service:

Now, to read this, we can define a new function to get a URI using HttpClient. This uses async which blocks until the call is complete:

static async Task<string> GetURI(Uri u)
{
var response = string.Empty;
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.GetAsync(u);
if (result.IsSuccessStatusCode)
{
response = await result.Content.ReadAsStringAsync();
}
}
return response;
}

We can call our new function by:

var t = Task.Run(() => GetURI(new Uri("http://localhost:31404/Api/Customers")));
t.Wait();

Console.WriteLine(t.Result);
Console.ReadLine();

This receives a response from our web service and displays it in the console:

To parse out the returned JSON, add a reference to Newtonsoft:

Change the code to use JArray using Newtonsoft.Json.Linq:

            var t = Task.Run(() => GetURI(new Uri("http://localhost:31404/Api/Customers")));
            t.Wait();

            JArray j = JArray.Parse(t.Result);
            Console.WriteLine(j);
            Console.ReadLine();

This now looks like:

Now, to create a new record using our REST service, we will use HttpPost with HttpClient PostAsync.

We will create a function PostURI which calls HttpClient PostAsync, then returns the StatusCode:

static async Task<string> PostURI(Uri u, HttpContent c)
{
var response = string.Empty;
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.PostAsync(u, c);
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}
return response;
}

We will call it by creating a string that we will use to post:

            Uri u = new Uri("http://localhost:31404/Api/Customers");
            var payload = "{\"CustomerId\": 5,\"CustomerName\": \"Pepsi\"}";

            HttpContent c = new StringContent(payload, Encoding.UTF8, "application/json");
            var t = Task.Run(() => PostURI(u, c));
            t.Wait();

            Console.WriteLine(t.Result);
            Console.ReadLine();

Running this produces:

The backend database shows the new record created:

Using SendAsync, we can write the code as:

        static async Task SendURI(Uri u, HttpContent c)
        {
            var response = string.Empty;
            using (var client = new HttpClient())
            {
                HttpRequestMessage request = new HttpRequestMessage
                {
                    Method = HttpMethod.Post,
                    RequestUri = u,
                    Content = c
                };

                HttpResponseMessage result = await client.SendAsync(request);
                if (result.IsSuccessStatusCode)
                {
                    response = result.StatusCode.ToString();
                }
            }
            return response;

Calling it:

            Uri u = new Uri("http://localhost:31404/Api/Customers");
            var payload = "{\"CustomerId\": 5,\"CustomerName\": \"Pepsi\"}";

            HttpContent c = new StringContent(payload, Encoding.UTF8, "application/json");
            var t = Task.Run(() => SendURI(u, c));
            t.Wait();

            Console.WriteLine(t.Result);
            Console.ReadLine();

Note instead of sending a JSON string, we can create a class/object and serialize it:

            var payload = new Dictionary<string, string>
            {
              {"CustomerId", "5"},
              {"CustomerName", "Pepsi"}
            };

            string strPayload = JsonConvert.SerializeObject(payload);
            HttpContent c = new StringContent(strPayload, Encoding.UTF8, "application/json");
            var t = Task.Run(() => SendURI(u, c));

 

THANKS FOR READING. BEFORE YOU LEAVE, I NEED YOUR HELP.
 

I AM SPENDING MORE TIME THESE DAYS CREATING YOUTUBE VIDEOS TO HELP PEOPLE LEARN THE MICROSOFT POWER PLATFORM.

IF YOU WOULD LIKE TO SEE HOW I BUILD APPS, OR FIND SOMETHING USEFUL READING MY BLOG, I WOULD REALLY APPRECIATE YOU SUBSCRIBING TO MY YOUTUBE CHANNEL.

THANK YOU, AND LET'S KEEP LEARNING TOGETHER.

CARL

https://www.youtube.com/carldesouza

 

ABOUT CARL DE SOUZA

Carl de Souza is a developer and architect focusing on Microsoft Dynamics 365, Power BI, Azure, and AI.

carldesouza.comLinkedIn Twitter | YouTube

 

10 Responses to HttpClient GetAsync, PostAsync, SendAsync in C#

  1. if your auth goes in the header like this -> client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Bearer”, “huge long token”); this is after you instantiate HttpClient

  2. Nice article, but HttpClient is intended to be instantiated as a static instance. This is because the object will not over-subscribe if there’s more requests than it can comfortably assign to sockets. If you create a separate object per request, then each object only knows about its active request, and so they will each think that there are plenty of sockets available. This will throw exceptions when a lot of requests are being done at the same time.

    For more info, check out the .NET API documentation for HttpClient in the Remarks section.

  3. Hi Carl,

    Good Day,
    I am getting an error in the below source code.
    Could you please help me with this.

    Error details

    Newtonsoft.Json.JsonSerializationException: ‘Cannot deserialize the current JSON array (e.g. [1,2,3]) into type ‘LSI.Web.Models.ResponseDto’ because the type requires a JSON object (e.g. {“name”:”value”}) to deserialize correctly.

    To fix this error either change the JSON to a JSON object (e.g. {“name”:”value”}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

    Path ”, line 1, position 1.’

    Error Line
    var apiRespnseDto = JsonConvert.DeserializeObject(apiContent); // Error Line

    Code details are below

    public interface IBaseService : IDisposable
    {
    ResponseDto responseModel { get; set; }

    Task SendAsync(ApiRequest apiRequest);

    }

    Baseservice.cs
    public async Task SendAsync(ApiRequest apiRequest)
    {
    try
    {
    var client = httpClient.CreateClient(“LSIAPI”);
    HttpRequestMessage message = new HttpRequestMessage();
    message.Headers.Add(“Accept”, “application/json”);
    message.RequestUri = new Uri(apiRequest.Url);
    client.DefaultRequestHeaders.Clear();
    if (apiRequest.Data != null)
    {
    message.Content = new StringContent(JsonConvert.SerializeObject(apiRequest.Data),
    Encoding.UTF8, “application/json”);
    }

    HttpResponseMessage apiResponse = null;
    switch (apiRequest.ApiType)
    {
    case SD.ApiType.POST:
    message.Method = HttpMethod.Post;
    break;
    case SD.ApiType.PUT:
    message.Method = HttpMethod.Put;
    break;
    case SD.ApiType.DELETE:
    message.Method = HttpMethod.Delete;
    break;
    default:
    message.Method = HttpMethod.Get;
    break;
    }

    apiResponse = await client.SendAsync(message);
    var apiContent = await apiResponse.Content.ReadAsStringAsync();
    var apiRespnseDto = JsonConvert.DeserializeObject(apiContent);
    return apiRespnseDto;

    }
    catch (Exception ex)
    {
    var dto = new ResponseDto
    {
    Displaymessage = “Error”,
    ErrorMessages = new List { Convert.ToString(ex.Message) },
    IsSuccess = false
    };
    var res = JsonConvert.SerializeObject(dto);
    var apiResponseDto = JsonConvert.DeserializeObject(res);
    return apiResponseDto;

    }
    }

    Thanks

    Rajesh Somvanshi

  4. Hi Carl,

    Hope you are doing Good.
    I am getting an error in the below line.I am Using the Patchasync and Used the above code as well but still same error.
    var result = client.PatchAsync(crmODataQuery, httpContent);
    (OR)
    HttpResponseMessage result = await client.SendAsync(request);

    Could you please help me with this. I am passing the Bearer token as Authentication Header. When i use the generated token in Postman by selecting Patch request its working fine and able to update the entity status in CRM. But when i run this through this code, facing this error.

    Error details:
    StatusCode: 401, ReasonPhrase: ‘Unauthorized’, Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent,

Leave a Reply

Your email address will not be published. Required fields are marked *