Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Whenever you need to access data from GitHub, create a client with a name of `gi
}
```

This method returns the string describing the collection of issues in the *dotnet/docs* GitHub repository. It returns content in JSON format and is deserialized into appropriate GitHub issue objects. There are many ways that you can configure the `HttpClientFactory` to deliver preconfigured `HttpClient` objects. Try configuring multiple `HttpClient` instances with different names and endpoints for the various web services you work with. This approach will make your interactions with those services easier to work with on each page. For more details, read [the documentation for the IHttpClientFactory](/aspnet/core/fundamentals/http-requests).
This method returns the string describing the collection of issues in the *dotnet/docs* GitHub repository. It returns content in JSON format and is deserialized into appropriate GitHub issue objects. There are many ways that you can configure the `HttpClientFactory` to deliver preconfigured `HttpClient` objects. Try configuring multiple `HttpClient` instances with different names and endpoints for the various web services you work with. This approach will make your interactions with those services easier to work with on each page. For more information, see [Make HTTP requests using IHttpClientFactory](/aspnet/core/fundamentals/http-requests).

>[!div class="step-by-step"]
>[Previous](forms-validation.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ms.date: 04/06/2022

The first line of defense is application resiliency.

While you could invest considerable time writing your own resiliency framework, such products already exist. [Polly](https://dotnetfoundation.org/projects/polly) is a comprehensive .NET resilience and transient-fault-handling library that allows developers to express resiliency policies in a fluent and thread-safe manner. Polly targets applications built with either the .NET Framework or .NET 6. The following table describes the resiliency features, called `policies`, available in the Polly Library. They can be applied individually or grouped together.
While you could invest considerable time writing your own resiliency framework, such products already exist. [Polly](https://dotnetfoundation.org/projects/polly) is a comprehensive .NET resilience and transient-fault-handling library that allows developers to express resiliency policies in a fluent and thread-safe manner. Polly targets applications built with either .NET Framework or .NET 6. The following table describes the resiliency features, called `policies`, available in the Polly Library. They can be applied individually or grouped together.

| Policy | Experience |
| :-------- | :-------- |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ public class CatalogService : ICatalogService
}
```

Notice how no Dapr specific code is required to make the service invocation call. All communication is done using the standard HttpClient object.
Notice how no Dapr-specific code is required to make the service invocation call. All communication is done using the standard HttpClient object.

The Dapr HttpClient is configured for the `CatalogService` class on program startup:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ The following steps show how you can use Http retries with Polly integrated into

**Reference the .NET 6 packages**

`IHttpClientFactory` is available since .NET Core 2.1 however we recommend you to use the latest .NET 6 packages from NuGet in your project. You typically also need to reference the extension package `Microsoft.Extensions.Http.Polly`.
`IHttpClientFactory` is available since .NET Core 2.1, however, we recommend you use the latest .NET 6 packages from NuGet in your project. You typically also need to reference the extension package `Microsoft.Extensions.Http.Polly`.

**Configure a client with Polly's Retry policy, in Startup**

As shown in previous sections, you need to define a named or typed client HttpClient configuration in your standard Startup.ConfigureServices(...) method, but now, you add incremental code specifying the policy for the Http retries with exponential backoff, as below:
As shown in previous sections, you need to define a named or typed client HttpClient configuration in your standard `Startup.ConfigureServices(...)` method, but now, you add incremental code specifying the policy for the Http retries with exponential backoff, as below:

```csharp
//ConfigureServices() - Startup.cs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Second, you'll need to regenerate the service client with the new tools present

After the migration, if you find that there are libraries you need that aren't present on .NET, you can add a reference to the [Microsoft.Windows.Compatibility](https://www.nuget.org/packages/Microsoft.Windows.Compatibility) NuGet package and see if the missing functions are there.

If you're using the <xref:System.Net.WebRequest> class to perform web service calls, you may find some differences on .NET. The recommendation is to use the System.Net.Http.HttpClient instead.
If you're using the <xref:System.Net.WebRequest> class to perform web service calls, you may find some differences on .NET. The recommendation is to use <xref:System.Net.Http.HttpClient> instead.

## Consuming a COM Object

Expand Down
31 changes: 17 additions & 14 deletions docs/core/extensions/http-client.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
---
title: HTTP with .NET
title: IHttpClientFactory with .NET
description: Learn how to use the HttpClient and IHttpClientFactory implementations with dependency injection in your .NET workloads.
author: IEvangelist
ms.author: dapine
ms.date: 11/12/2021
---

# HTTP with .NET
# IHttpClientFactory with .NET

In this article, you'll learn how to use the `IHttpClientFactory` and the `HttpClient` types with various .NET fundamentals, such as dependency injection (DI), logging, and configuration. The <xref:System.Net.Http.HttpClient> type was introduced in .NET Framework 4.5, which was released in 2012. In other words, it's been around for a while. `HttpClient` is used for making HTTP requests and handling HTTP responses from web resources identified by a <xref:System.Uri>. The HTTP protocol makes up the vast majority of all internet traffic.

With modern application development principles driving best practices, the <xref:System.Net.Http.IHttpClientFactory> serves as a factory abstraction that can create `HttpClient` instances with custom configurations. <xref:System.Net.Http.IHttpClientFactory> was introduced in .NET Core 2.1. Common HTTP-based .NET workloads can take advantage of resilient and transient-fault-handling third-party middleware with ease.

## Explore the `IHttpClientFactory` type
> [!NOTE]
> If your app requires cookies, it might be better not to use <xref:System.Net.Http.IHttpClientFactory> in your app. For alternative ways of managing clients, see [Guidelines for using HTTP clients](../../fundamentals/networking/httpclient-guidelines.md).

All of the sample source code in this article relies on the [`Microsoft.Extensions.Http`](https://www.nuget.org/packages/microsoft.extensions.http) NuGet package. Additionally, [The Internet Chuck Norris Database](https://www.icndb.com) free API is used to make HTTP GET requests for "nerdy" jokes.
## The `IHttpClientFactory` type

All of the sample source code in this article relies on the [`Microsoft.Extensions.Http`](https://www.nuget.org/packages/microsoft.extensions.http) NuGet package. Additionally, [The Internet Chuck Norris Database](https://www.icndb.com) free API is used to make HTTP `GET` requests for "nerdy" jokes.

When you call any of the <xref:Microsoft.Extensions.DependencyInjection.HttpClientFactoryServiceCollectionExtensions.AddHttpClient%2A> extension methods, you're adding the `IHttpClientFactory` and related services to the <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection>. The `IHttpClientFactory` type offers the following benefits:

Expand Down Expand Up @@ -145,16 +148,16 @@ The defined interface can be consumed where necessary, with the implementation p

## Make POST, PUT, and DELETE requests

In the preceding examples, all HTTP requests use the GET HTTP verb. `HttpClient` also supports other HTTP verbs, including:
In the preceding examples, all HTTP requests use the `GET` HTTP verb. `HttpClient` also supports other HTTP verbs, including:

- POST
- PUT
- DELETE
- PATCH
- `POST`
- `PUT`
- `DELETE`
- `PATCH`

For a complete list of supported HTTP verbs, see <xref:System.Net.Http.HttpMethod>.

The following example shows how to make an HTTP POST request:
The following example shows how to make an HTTP `POST` request:

:::code source="snippets/http/basic/ItemService.cs" id="Create":::

Expand All @@ -167,13 +170,13 @@ In the preceding code, the `CreateItemAsync` method:

`HttpClient` also supports other types of content. For example, <xref:System.Net.Http.MultipartContent> and <xref:System.Net.Http.StreamContent>. For a complete list of supported content, see <xref:System.Net.Http.HttpContent>.

The following example shows an HTTP PUT request:
The following example shows an HTTP `PUT` request:

:::code source="snippets/http/basic/ItemService.cs" id="Update":::

The preceding code is very similar to the POST example. The `UpdateItemAsync` method calls <xref:System.Net.Http.HttpClient.PutAsync%2A> instead of `PostAsync`.
The preceding code is very similar to the `POST` example. The `UpdateItemAsync` method calls <xref:System.Net.Http.HttpClient.PutAsync%2A> instead of `PostAsync`.

The following example shows an HTTP DELETE request:
The following example shows an HTTP `DELETE` request:

:::code source="snippets/http/basic/ItemService.cs" id="Delete":::

Expand All @@ -199,7 +202,7 @@ services.AddHttpClient("Named.Client")
> [!IMPORTANT]
> You can generally treat `HttpClient` instances as objects that **do not** require disposal. Disposal cancels outgoing requests and guarantees the given `HttpClient` instance can't be used after calling <xref:System.IDisposable.Dispose%2A>. `IHttpClientFactory` tracks and disposes resources used by `HttpClient` instances.

Keeping a single `HttpClient` instance alive for a long duration is a common pattern used before the inception of `IHttpClientFactory`. This pattern becomes unnecessary after migrating to `IHttpClientFactory`.
Keeping a single `HttpClient` instance alive for a long duration is a common pattern used before the inception of `IHttpClientFactory`. For information about which strategy to use in your app, see [Guidelines for using HTTP clients](../../fundamentals/networking/httpclient-guidelines.md).

## Configure the `HttpMessageHandler`

Expand Down
3 changes: 3 additions & 0 deletions docs/core/tools/dotnet-environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ The `AppContext` switch can also be set by a config file. For more information c

The same can be achieved via the environment variable `DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER`. To opt-out, set the value to either `false` or `0`.

> [!NOTE]
> Starting in .NET 5, this setting to use <xref:System.Net.Http.HttpClientHandler> is no longer available.

### `DOTNET_Jit*` and `DOTNET_GC*`

There are two stressing-related features for the JIT and JIT-generated GC information: JIT Stress and GC Hole Stress. These features provide a way during development to discover edge cases and more "real world" scenarios without having to develop complex applications. The following environment variables are available:
Expand Down
2 changes: 1 addition & 1 deletion docs/framework/wcf/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Support has been added to allow for WCF services with Internationalized Domain N

## HttpClient

A new class called <xref:System.Net.Http.HttpClient> has been added to make working with HTTP requests much easier. For more info, see [HTTP with .NET](../../core/extensions/http-client.md).
A new class called <xref:System.Net.Http.HttpClient> has been added to make working with HTTP requests much easier. For more info, see <xref:System.Net.Http.HttpClient> and [Guidelines for using HTTP clients](../../fundamentals/networking/httpclient-guidelines.md).

## Configuration IntelliSense

Expand Down
4 changes: 2 additions & 2 deletions docs/fundamentals/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ landingContent:
url: ../core/extensions/workers.md
- text: Caching in .NET
url: ../core/extensions/caching.md
- text: HTTP with .NET
url: ../core/extensions/http-client.md
- text: HTTP in .NET
url: networking/httpclient-guidelines.md
- text: Localization in .NET
url: ../core/extensions/localization.md
- text: File globbing in .NET
Expand Down
35 changes: 35 additions & 0 deletions docs/fundamentals/networking/httpclient-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: HTTPClient guidelines for .NET
description: Learn about using HttpClient instances to send HTTP requests and how you can manage clients using IHttpClientFactory in your .NET apps.
author: gewarren
ms.author: gewarren
ms.date: 05/19/2022
---
# Guidelines for using HTTPClient

The <xref:System.Net.Http.HttpClient?displayProperty=fullName> class sends HTTP requests and receives HTTP responses from a resource identified by a URI. An <xref:System.Net.Http.HttpClient> instance is a collection of settings that's applied to all requests executed by that instance, and each instance uses its own connection pool, which isolates its requests from others. Starting in .NET Core 2.1, the <xref:System.Net.Http.SocketsHttpHandler> class provides the implementation, making behavior consistent across all platforms.

If you're using .NET 5+ (including .NET Core), there are some considerations to keep in mind if you're using <xref:System.Net.Http.HttpClient>.

## DNS behavior

<xref:System.Net.Http.HttpClient> only resolves DNS entries when a connection is created. It does not track any time to live (TTL) durations specified by the DNS server. If DNS entries change regularly, which can happen in some container scenarios, the client won't respect those updates. To solve this issue, you can limit the lifetime of the connection by setting the <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime> property, so that DNS lookup is required when the connection is replaced.

## Pooled connections

In .NET Framework, disposing <xref:System.Net.Http.HttpClient> objects does not impact connection management. However, in .NET Core, the connection pool is linked to the client's underlying <xref:System.Net.Http.HttpMessageHandler>. When the <xref:System.Net.Http.HttpClient> instance is disposed, it disposes all previously used connections. If you later send a request to the same server, a new connection is created. There's also a performance penalty because it needs a new TCP port. If the rate of requests is high, or if there are any firewall limitations, that can **exhaust the available sockets** because of default TCP cleanup timers.

## Recommended use

- In .NET Framework, you can create a new <xref:System.Net.Http.HttpClient> each time you need to send a request.
- In .NET Core and .NET 5+:
- Use a static or singleton <xref:System.Net.Http.HttpClient> with <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime> set to a desired interval, such as two minutes, depending on expected DNS changes. This solves both the socket exhaustion and DNS changes problems without adding the overhead of <xref:System.Net.Http.IHttpClientFactory>. If you need to be able to mock your handler, you can register it separately.
- Using <xref:System.Net.Http.IHttpClientFactory>, you can have multiple, differently configured clients for different use cases. If its lifetime hasn't expired, an <xref:System.Net.Http.HttpMessageHandler> instance may be reused from the pool when the factory creates a new <xref:System.Net.Http.HttpClient> instance. This reuse avoids any socket exhaustion issues. If you desire the configurability that <xref:System.Net.Http.IHttpClientFactory> provides, we recommend using the [typed-client approach](../../core/extensions/http-client.md#typed-clients). However, be aware that the clients created by the factory are intended to be short-lived, and once the client is created, the factory no longer has control over it.

> [!TIP]
> If your app requires cookies, consider disabling automatic cookie handling or avoiding <xref:System.Net.Http.IHttpClientFactory>. Pooling the <xref:System.Net.Http.HttpMessageHandler> instances results in sharing of <xref:System.Net.CookieContainer> objects. Unanticipated <xref:System.Net.CookieContainer> object sharing often results in incorrect code.

## See also

- [Make HTTP requests using IHttpClientFactory](/aspnet/core/fundamentals/http-requests)
- [Use IHttpClientFactory to implement resilient HTTP requests](../../architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests.md)
13 changes: 9 additions & 4 deletions docs/fundamentals/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2496,10 +2496,15 @@ items:
href: ../core/extensions/console-log-formatter.md
- name: HostBuilder (generic host)
href: ../core/extensions/generic-host.md
- name: HTTP with .NET
href: ../core/extensions/http-client.md
- name: HTTP/3 with .NET
href: ../core/extensions/httpclient-http3.md
- name: Networking
items:
- name: HTTP clients in .NET
displayName: networking, httpclient
href: networking/httpclient-guidelines.md
- name: IHttpClientFactory
href: ../core/extensions/http-client.md
- name: HTTP/3 with .NET
href: ../core/extensions/httpclient-http3.md
- name: File globbing in .NET
href: ../core/extensions/file-globbing.md
- name: Primitives library in .NET
Expand Down
4 changes: 3 additions & 1 deletion docs/standard/runtime-libraries-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ Some libraries are provided in NuGet packages rather than included in the runtim
| [Dependency injection](../core/extensions/dependency-injection.md) | [`Microsoft.Extensions.DependencyInjection`][di] |
| [File globbing](../core/extensions/file-globbing.md) | [`Microsoft.Extensions.FileSystemGlobbing`][fsg] |
| [Generic Host](../core/extensions/generic-host.md) | [`Microsoft.Extensions.Hosting`][host] |
| [HTTP](../core/extensions/http-client.md) | [`Microsoft.Extensions.Http`][http] |
| [HTTP](../core/extensions/http-client.md) | [`Microsoft.Extensions.Http`]<sup>1</sup>[http] |
| [Localization](../core/extensions/localization.md) | [`Microsoft.Extensions.Localization`][loc] |
| [Logging](../core/extensions/logging.md) | [`Microsoft.Extensions.Logging`][log] |

<sup>1</sup>For some target frameworks, including `net6.0`, these types are part of the shared framework and don't need to be installed separately.

[configuration]: https://www.nuget.org/packages/Microsoft.Extensions.Configuration
[di]: https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection
[fsg]: https://www.nuget.org/packages/Microsoft.Extensions.FileSystemGlobbing
Expand Down