Simple guide: send a POST request with C#

I tried to learn how to send a POST request using C# (to use with an Azure Function App I built) but all the tutorials I found were difficult and complex and confusing, and yes it is a complex confusing topic but there has to be an easier way.

So here’s a tutorial that might not be 100% right (it certainly isn’t) but should get you up and running with the basics. This is also very much written for beginners, by a beginner.

UPDATE: Most of this isn’t best practice, but if you’re at the level that matters, you shouldn’t be looking at this anyways.

Sending a POST request in C# / .NET

First, we need to set up the HttpClient. Since HttpClient is a disposable resource (and therefore garbage collection doesn’t really happen on it) we have to make sure that we make it, then also delete it once we’re done.

To do this easily, we’ll use a using block:

C#
using System.Net.Http;
using System.Threading.Tasks;

namespace Benbarnett02;

internal class BlogPost{

  public static async Task<string> Post() {
    using (HttpClient myHttpClient = new HttpClient())
    {
       // Most of our code will go in here.
    }
  }
}

You’ll also want to be familiar with asynchronous programming as it’s (almost) essential for working with HTTP requests in C#.

Ideally, we should reuse this HttpClient for all the requests we want to make. This isn’t always practical, but doing this will greatly improve performance if you have multiple requests. ASP.NET Monsters has a great post on why this is important, and the better way to do this (the way I’m doing it is easy and correct but not ideal).

Now that we have a HttpClient, let’s look at setting up the request.

Setting the API URI

To set the API we want to interact with, we need to give the HttpClient.BaseAddress a Uri object by adding this inside our using block:

C#
myHttpClient.BaseAddress = new Uri("https://example.com/");

Adding Request Headers

The easy (slightly lazy) way to add request headers is to add them using the Add method of the HttpClient.DefaultRequestHeaders class. For example, you could add the following inside the using block:

C#
string myCredential = "Bearer password123";
myHttpClient.DefaultRequestHeaders.Add("Accept", "application/json");
myHttpClient.DefaultRequestHeaders.Add("Authorization", myCredential);

A note on authorization

Basically, there’s a sorta-better way that I’ll address in another blog post. You should not be putting credentials in code. To clarify:

  • You should not be putting credentials in code
  • Don’t put credentials in code
  • Code shouldn’t contain credentials
  • Don’t commit credentials to your source control/git repo
  • stop it. don’t do what I’m doing, it’s just for this example.

Adding body content

This part is a little tricky, because it relies on a bit of knowledge about the exact format of the data you need to POST. The quick and dirty way is to just use a string like follows:

C#
string body = "Hi there!";
StringContent bodyContent = new StringContent(body, Encoding.UTF8, "text/plain");

Note that this literally just sends some text to the API – not the most useful.

StringContent provides HTTP body data based on the string we give it, the encoding we specify, and the content type (i.e. text/plain or application/json)

I’ll do a proper post on how to craft various content types at some point.

Full send it aye

To actually send the request, we use the following (and specify the request endpoint & body).

C#
HttpResponseMessage myHttpResponse = await myHttpClient.PostAsync("/foo", bodyContent);

That sends the request asynchronously, but then awaits the response to put into a HttpResponseMessage object, “myHttpResponse”.

Using the response

In my case, I chose to read the JSON response as a class that I made.

C#
MyObject responseObject = await httpResponse.Content.ReadAsAsync<MyObject>();

Full Example Code

C#
using System.Net.Http;
using System.Threading.Tasks;

namespace Benbarnett02;

internal class BlogPost{

  public static async Task<string> Post(){
    using (HttpClient myHttpClient = new HttpClient())
    {
       // Most of our code will go in here.
       // Set a base address
      myHttpClient.BaseAddress = new Uri("https://example.com/");
      // Don't put creds in code
      string myCredential = "Bearer password123";
      // Add headers
      myHttpClient.DefaultRequestHeaders.Add("Accept", "application/json");
      myHttpClient.DefaultRequestHeaders.Add("Authorization", myCredential);
      
      // Add content
      string body = "Hi there!";
      StringContent bodyContent = new StringContent(body, Encoding.UTF8, "text/plain");
      
      // Post to example.com/foo with our content
      HttpResponseMessage myHttpResponse = await myHttpClient.PostAsync("/foo", bodyContent);
      // Deal with the reply
      MyObject responseObject = await httpResponse.Content.ReadAsAsync<MyObject>();
    }
  }
}

P.S. I think this is all right, I wrote this a while ago and saved a draft so not sure. What’s the worst that could go wrong.

Leave a Reply

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