Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use HttpClient asynchronously, convert JSON to typed C# objects with System.Net.Http.Json, and check the HTTP response before treating an API operation as successful. A small utility can reuse one HttpClient; a console app that uses dependency injection or needs several configured clients can use IHttpClientFactory.

Make a GET request from a console app

Create a console project with the .NET SDK:

dotnet new console

Then send an awaited request and deserialize the JSON response. This example uses a placeholder endpoint; replace it with an address and response model that match your API.

using System.Net.Http.Json;

using var client = new HttpClient
{
    BaseAddress = new Uri("https://api.example.com/")
};

var item = await client.GetFromJsonAsync<Item>("api/items/1");

public sealed class Item
{
    public int Id { get; set; }
    public string? Name { get; set; }
}

Microsoft’s console-app tutorial demonstrates an awaited GET request and converting the JSON response into C# objects. HttpClient’s long-running operations are asynchronous, so await them rather than blocking with .Result or .Wait().

Set the base address and request headers correctly

When you use BaseAddress with a relative request URI, end the base address with a forward slash and do not start the relative path with one. For example, https://api.example.com/ plus api/items/1 resolves beneath that base address. A leading slash changes URI resolution and can discard a path segment from the base address.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Microsoft states: “The HttpClient.BaseAddress property should be set to an address with a trailing forward slash (/).” See Call a Web API From a .NET Client (C#).

Set headers required by the particular service. An Accept header can indicate that the client expects JSON; some services also require a User-Agent. The Microsoft console example uses both. Follow the API’s authentication requirements as well; there is no universal credential format.

Deserialize JSON into C# types

The System.Net.Http.Json extensions make common JSON operations concise:

  • GetFromJsonAsync<T> sends a GET request and deserializes its response body to T.
  • ReadFromJsonAsync<T> deserializes JSON from an existing HttpContent response body.
  • For custom naming policies, converters, or source-generation settings, use System.Text.Json with explicit JsonSerializerOptions.

The Microsoft HttpClient guidance describes these extensions as automatic JSON serialization and deserialization using System.Text.Json. Model the API’s actual response shape: a JSON object, array, or nullable field may not map to the type you first expect.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle status codes and API errors

A completed HTTP call does not by itself mean the requested business operation succeeded. Check the status code and, where the API contract provides useful details, read the response body. For straightforward code, call EnsureSuccessStatusCode() so a non-success HTTP status becomes an exception instead of passing unnoticed.

For writes, serialize the request model as JSON and send it with PostAsync or PutAsync; use DeleteAsync for removal. Microsoft’s factory guidance shows JSON request content and EnsureSuccessStatusCode() after POST, PUT, and DELETE calls. The CRUD tutorial demonstrates the conventional GET, POST, PUT, and DELETE methods.

Choose the error-handling approach that fits the app. EnsureSuccessStatusCode() is simple when exceptions are appropriate; inspect HttpResponseMessage.StatusCode directly when the program needs different actions for different responses. In either case, use the API’s contract to interpret the status and any error content.

Choose a client lifetime: reuse HttpClient or use IHttpClientFactory

Approach Fits best when What it provides
One reused HttpClient A small, straightforward console utility has one backend configuration. A simple client to reuse throughout the application lifetime; Microsoft recommends reusing HttpClient instances.
IHttpClientFactory The console app uses dependency injection, has multiple backend configurations, or needs factory-managed client patterns. Basic, named, typed, and generated client patterns, plus configuration through dependency injection.

For a small utility, reusing a single client is generally the simplest option. For a host-based console app using dependency injection, Microsoft’s IHttpClientFactory guidance requires Microsoft.Extensions.Hosting and Microsoft.Extensions.Http, followed by registration with AddHttpClient.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Named clients suit multiple configurations for different API endpoints.
  • Typed clients encapsulate operations for one backend.
  • Generated clients can fit a toolchain that includes an API description and client generator.

Consider application size, dependency-injection needs, the number of backend configurations, customization requirements, and testability when choosing. Factory patterns are useful when their configuration and organization benefits justify the additional setup.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Prepare the example for a real API

Before relying on a console client in routine use, adapt it to the target service rather than treating the short GET example as complete production handling:

  • Use the authentication mechanism required by that API.
  • Set a cancellation path for operations that should stop when the user or host cancels the work.
  • Choose timeout behavior appropriate to the operation.
  • Add logging where useful for diagnosing requests and failures.
  • Check status codes and interpret response content against the API contract.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.