C# – Get and send JSON with HttpClient

The simplest way to get and send JSON with HttpClient is to use the GetFromJsonAsync() and PostAsJsonAsync() extension methods (in System.Net.Http.Json), like this:

using System.Net.Http.Json;

//Get JSON
var stock = await httpClient.GetFromJsonAsync<Stock>($"https://localhost:12345/stocks/{symbol}");

stock.Price = 121.10m;

//Send JSON
await httpClient.PostAsJsonAsync<Stock>("https://localhost:12345/stocks/", stock);
Code language: C# (cs)

Note: You have to install the System.Net.Http.Json package if you’re using a framework version before .NET 5.

These extension methods use System.Text.Json for serialization. They simplify things by abstracting away the common steps involved in sending and getting JSON. Compare this approach with the manual way of doing it (see the What if you want to use Newtonsoft? section below).

To customize serialization, you can pass in a JsonSerializerOptions object. I’ll show an example of that below.

If you’re using a version before .NET 5, install the System.Net.Http.Json nuget package

Microsoft added System.Net.Http.Json to the framework starting in .NET 5. If you’re using a framework version before .NET 5, you have to install the package:

Install-Package System.Net.Http.Json
Code language: PowerShell (powershell)

Note: This is using Package Manager Console (View > Other Windows > Package Manager Console).

Customize JSON serialization when using HttpClient

To customize serialization, you can pass in a JsonSerializerOptions object. If you need to customize something that the default options don’t support, then you can create a custom JSON converter.

Here’s an example. By default, System.Text.Json serializes enum values instead of names, like this:

{
	"symbol": "VTSAX",
	"price": 106.5,
	"quoteTime": "2021-07-20T14:04:00.3381111-04:00",
	"fundType": 1
}
Code language: JSON / JSON with Comments (json)

Let’s say you want to make it serialize the enum name instead. You can do that by passing in JsonSerializerOptions with JsonStringEnumConverter, like this:

using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;

var stock = new Stock()
{
	Symbol = "VTSAX",
	FundType = FundTypes.MutualFund,
	Price = 106.5m,
	QuoteTime = DateTimeOffset.Now
};

var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
options.Converters.Add(new JsonStringEnumConverter());

await httpClient.PostAsJsonAsync<Stock>("https://localhost:12345/stocks/", stock, options);


Code language: C# (cs)

This generates the following JSON. Notice the FundType property is using the enum name instead of the value:

{
	"symbol": "VTSAX",
	"price": 106.5,
	"quoteTime": "2021-07-20T15:18:39.7460603-04:00",
	"fundType": "MutualFund"
}
Code language: JSON / JSON with Comments (json)

Use JsonSerializerDefaults.Web

If you don’t pass in a JsonSerializerOptions object, then System.Net.Http.Json uses the JsonSerializerDefaults.Web options, which has the following settings:

var options = new JsonSerializerOptions()
{
	PropertyNameCaseInsensitive = true,
	PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
	NumberHandling = JsonNumberHandling.AllowReadingFromString
};
Code language: C# (cs)

When you’re creating your own options object to customize serialization, you’ll need to pass in the JsonSerializerDefaults.Web constructor parameter if you want to use the “web defaults.”

What if you want to use Newtonsoft?

The System.Net.Http.Json extension methods provide a nice, convenient way to deal with JSON when you’re using HttpClient. The downside is that it forces you to use System.Text.Json. What if you want to use Newtonsoft instead (or just want to handle this manually)?

Here’s an example of getting JSON with HttpClient and deserializing it with Newtonsoft:

using Newtonsoft.Json;

var symbol = "VTSAX";
var response = await httpClient.GetAsync($"https://localhost:12345/stocks/{symbol}");

response.EnsureSuccessStatusCode();

var json = await response.Content.ReadAsStringAsync();

var stock = JsonConvert.DeserializeObject<Stock>(json);

Console.WriteLine($"Stock {stock.Symbol} ({stock.FundType}) = {stock.Price}");
Code language: C# (cs)

Note: Compare this with the one-liner httpClient.GetFromJsonAsync<Stock>(url);

This outputs:

Stock VTSAX (MutualFund) = 107Code language: plaintext (plaintext)

Here’s an example of serializing an object to JSON with Newtonsoft and then sending it with HttpClient:

using Newtonsoft.Json;

var stock = new Stock()
{
	Symbol = "VTSAX",
	FundType = FundTypes.MutualFund,
	Price = 106.5m,
	QuoteTime = DateTimeOffset.Now
};

var json = JsonConvert.SerializeObject(stock);

var response = await httpClient.PostAsync("https://localhost:12345/stocks/", 
	new StringContent(json, Encoding.UTF8, "application/json"));

response.EnsureSuccessStatusCode();
Code language: C# (cs)

Note: You may be interested in using the Newtonsoft extension methods for HttpClient instead of repeating this code over and over.