Explore HTTP clients in
Explore HTTP clients in
NET Core
Completed100 XP
7 minutes
The Hypertext Transfer Protocol (or HTTP) is used to request resources from a web server. Many
types of resources are available on the web, and HTTP defines a set of request methods for accessing
these resources. In .NET Core, those requests are made through an instance of the HttpClient.
There are two options for implementing HttpClient in your app and the recommendation is to choose
the implementation based on the clients lifetime management needs:
Long-lived clients: create a static or singleton instance using the HttpClient class and
set PooledConnectionLifetime
The System.Net.Http.HttpClient class sends HTTP requests and receives HTTP responses from a
resource identified by a URI. An HttpClient instance is a collection of settings applied to all requests
executed by that instance, and each instance uses its own connection pool, which isolates its
requests from others. Beginning with .NET Core 2.1, the SocketsHttpHandler class provides the
implementation, making behavior consistent across all platforms.
HttpClient only resolves DNS entries when a connection is created. It doesn't track time to live (TTL)
durations specified by the DNS server. If DNS entries change regularly the client is unaware those
updates. To solve this issue, you can limit the lifetime of the connection by setting
the PooledConnectionLifetime property, so that DNS lookup is repeated when the connection is
replaced.
In the following example, HttpClient is configured to reuse connections for 15 minutes. After
the TimeSpan specified by PooledConnectionLifetime elapses, the connection is closed and a new
one is created.
C#Copy
};
The IHttpClientFactory serves as a factory abstraction that can create HttpClient instances with
custom configurations. IHttpClientFactory was introduced in .NET Core 2.1. Common HTTP-
based .NET workloads can take advantage of middleware with ease.
When you call any of the AddHttpClient extension methods, you're adding the IHttpClientFactory and
related services to the IServiceCollection. The IHttpClientFactory type offers the following benefits:
Provides a central location for naming and configuring logical HttpClient instances.
Adds a configurable logging experience for all requests sent through clients created by the
factory.
You should let HttpClientFactory and the framework manage the lifetimes and instantiation
of HttpClient instances. The lifetime management helps avoid common issues such as DNS (Domain
Name System) problems that can occur when manually managing HttpClient lifetimes.
Basic usage
Named clients
Typed clients
Generated clients
Completed100 XP
10 minutes
In this unit, you learn how to use the IHttpClientFactory to handle the HTTP client creation and
disposal, and to use that client to perform REST operations in an ASP.NET Razor Pages app. The code
samples used throughout this unit are based on interacting with an API that enables managing a list
of fruit stored in a database.
The following code represents the data model that is referenced in the code examples:
C#Copy
To add IHttpClientFactory to your app, register the AddHttpClient in the Program.cs file. The
following code example uses the named client type and sets the base address of the API used in REST
operations, and is referenced throughout the rest of this unit.
C#Copy
builder.Services.AddRazorPages();
// Add IHttpClientFactory to the container and sets the name of the factory
// to "FruitAPI", and the also sets the base address used in calls
});
Before performing operations with an API, you need to identify what the API is expecting:
API endpoint: Identify the endpoint for the operation so you can properly adjust the URI
stored in the base address if needed.
For example, a GET operation could return an array if the endpoint returns all of the data, or any
number greater than one, stored in the database. A GET operation could also return a single piece of
data.
Note
The code samples throughout the rest of this unit assume each HTTP operation is handled on a
separate page in the solution.
In Razor Pages, handler methods are methods that handle HTTP requests and events. They're
defined in the code-behind file for a Razor Page and are used to perform actions in response to user
input or other events. Handler methods follow the naming convention of the word "On" added to
the beginning of the HTTP request verb. The following table lists some of the most commonly used
handler methods in Razor Pages:
Expand table
OnGet() This method is called when the page is requested using the HTTP GET method.
OnPost() This method is called when the page is submitted using the HTTP POST method.
Handler method Description
OnGetAsync() This method is called asynchronously when the page is requested using the HTTP GET method.
OnPostAsync() This method is called asynchronously when the page is submitted using the HTTP POST method.
OnGetHandler() This method is called when a specific handler is requested using the HTTP GET method.
OnPostHandler() This method is called when a specific handler is requested using the HTTP POST method.
There are also other handler methods that can be used for handling HTTP requests and events, and
you can define your own custom handler methods as well.
Note
You can only have one page handler method for a specific HTTP operation. For example, an exception
will be thrown if you have both OnGet() and OnGetAsync() in the same code-behind file.
A GET operation shouldn't send a body and is used (as the method name indicates) to retrieve data
from a resource. To perform an HTTP GET operation, given an HttpClient and a URI, use
the HttpClient.GetAsync method. For example, if you wanted to create a table on a Razor Page app's
home page (Index.cshtml) to display the results of a GET operation you need to add the following to
the code-behind (Index.cshtml.cs):
Use the [BindProperty] attribute to bind the pages form data to the data model properties.
Perform the GEToperation and deserialize the results into your data model.
The following code example shows how to perform a GET operation. Be sure to read the comments
in the code.
C#Copy
namespace FruitWebApp.Pages
_httpClientFactory = httpClientFactory;
// Adds the data model and binds the form data to the model properties
// Enumerable since an array is expected as a response
[BindProperty]
// Execute the GET operation and store the response, the empty parameter
// in GetAsync doesn't modify the base address set in the client factory
// If the operation is successful deserialize the results into the data model
if (response.IsSuccessStatusCode)
FruitModels = await
JsonSerializer.DeserializeAsync<IEnumerable<FruitModel>>(contentStream);
A POST operation should send a body and is used to add data to a resource. To perform an
HTTP POST operation, given an HttpClient and a URI, use the HttpClient.PostAsync method. Following
our project model of a separate page for eachIf you want to add items to the data on your home
page you need to:
For example, if you wanted to create a table on a Razor Page app's home page (Index.cshtml) to
display the results of a GET operation you need to add the following to the code-behind
(Index.cshtml.cs):
Use the [BindProperty] attribute to bind the pages form data to the data model properties.
Serialize the data you want to add using the JsonSerializer.Serialize method.
Note
Following our project model of a separate page for each REST operation the POST operation is
performed in an Add.cshtml page with the code example in the Add.cshtml.cs code-behind file.
The following code example shows how to perform a POST operation. Be sure to read the comments
in the code.
C#Copy
namespace FruitWebApp.Pages
// Add the data model and bind the form data to the page model properties
[BindProperty]
Encoding.UTF8,
"application/json");
// Execute the POST operation and store the response. The parameters in
// PostAsync direct the POST to use the base address and passes the
if (response.IsSuccessStatusCode)
return RedirectToPage("Index");
return Page();
Other operations like PUT and DELETE follow the same model as shown previously. The following
table defines common REST operations along with the associated HttpClient method:
Expand table
PUT HttpClient.PutAsync Updates an existing resource, or creates a new resource if it doesn't exist