-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DRAFT] Adding HttpWebRequest to HttpClient Migration Guide #42242
Draft
liveans
wants to merge
17
commits into
dotnet:main
Choose a base branch
from
liveans:httpwebrequest_migration_guide
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+956
−0
Draft
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
bf43ba6
Adding new file and basic start
liveans 3e3e670
Add complex examples
liveans b034fae
Add HttpWebRequest API Surface Mapping
liveans cb41c36
Change header styles
liveans 2708fc9
Try link
liveans 4b3df41
Adding more xrefs
liveans 054a11a
Add more examples and started to design sections
liveans c72c192
More sections
liveans 4e6b9a1
Fix broken link
liveans 6092dd4
Fix some todos and add new sections
liveans 5713947
More todo fix
liveans cc40883
Review feedbacks
liveans 846c262
Fix broken links
liveans c7ac137
Fix more todos
liveans ae0aa11
Add examples
liveans 368528f
Fix broken links
liveans fcf49af
Add DnsRoundRobin to build
liveans File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
136 changes: 136 additions & 0 deletions
136
docs/fundamentals/networking/http/httpclient-migrate-from-httpwebrequest.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
--- | ||
title: Migrate from HttpWebRequest | ||
description: Guidance document for migrating from HttpWebRequest to HttpClient. | ||
author: liveans | ||
ms.author: aaksoy | ||
ms.date: 07/25/2024 | ||
helpviewer_keywords: | ||
- "protocols, HTTP" | ||
- "migration, HTTP" | ||
- "HTTP" | ||
- "HttpWebRequest class, about HttpWebRequest class" | ||
- "application protocols, HTTP" | ||
- "HttpClient class, about HttpClient class" | ||
- "data requests, HTTP" | ||
- "Internet, HTTP" | ||
--- | ||
|
||
# HttpWebRequest to HttpClient Migration Guide | ||
|
||
This document aims to guide developers through the process of migrating from <xref:System.Net.HttpWebRequest>, <xref:System.Net.ServicePoint>, and <xref:System.Net.ServicePointManager> to <xref:System.Net.Http.HttpClient>. The migration is necessary due to the obsolescence of the older APIs and the numerous benefits offered by <xref:System.Net.Http.HttpClient>, including improved performance, better resource management, and a more modern and flexible API design. By following the steps outlined in this document, developers will be able to transition their codebases smoothly and take full advantage of the features provided by <xref:System.Net.Http.HttpClient>. | ||
|
||
## Migration steps | ||
|
||
Here is explanation for detailed migration steps. | ||
|
||
### Migrating from <xref:System.Net.HttpWebRequest> to <xref:System.Net.Http.HttpClient> | ||
|
||
The migration from <xref:System.Net.HttpWebRequest> to <xref:System.Net.Http.HttpClient> is essential due to the modern features and improved performance that <xref:System.Net.Http.HttpClient> offers. <xref:System.Net.Http.HttpClient> provides a more flexible and efficient way to make HTTP requests and handle responses. Here are the key steps and considerations for this migration: | ||
liveans marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Let's start with some examples: | ||
|
||
#### Simple GET Request Using <xref:System.Net.HttpWebRequest> | ||
|
||
Here's an example of how the code might look: | ||
|
||
```c# | ||
using System.Net; | ||
|
||
HttpWebRequest request = WebRequest.CreateHttp(uri); | ||
using WebResponse response = await request.GetResponseAsync(); | ||
``` | ||
|
||
#### Simple GET Request Using <xref:System.Net.Http.HttpClient> | ||
|
||
Here's an example of how the code might look: | ||
|
||
```c# | ||
using System.Net.Http; | ||
|
||
using HttpClient client = new(); | ||
liveans marked this conversation as resolved.
Show resolved
Hide resolved
|
||
using HttpResponseMessage message = await client.GetAsync(uri); | ||
``` | ||
|
||
#### Simple POST Request Using <xref:System.Net.HttpWebRequest> | ||
|
||
Here's an example of how the code might look: | ||
|
||
```c# | ||
using System.Net; | ||
|
||
HttpWebRequest request = WebRequest.CreateHttp(uri); | ||
request.Method = "POST"; | ||
request.ContentType = "text/plain"; | ||
await using Stream stream = await request.GetRequestStreamAsync(); | ||
await stream.WriteAsync("Hello World!"u8.ToArray()); | ||
using WebResponse response = await request.GetResponseAsync(); | ||
Memory<byte> buffer = new byte[1024]; | ||
await using Stream responseStream = response.GetResponseStream(); | ||
``` | ||
|
||
#### Simple POST Request Using <xref:System.Net.Http.HttpClient> | ||
|
||
Here's an example of how the code might look: | ||
|
||
```c# | ||
using System.Net.Http; | ||
|
||
using HttpClient client = new(); | ||
using HttpResponseMessage responseMessage = await client.PostAsync(uri, new StringContent("Hello World!")); | ||
``` | ||
|
||
## 1:1 API Mapping Table | ||
liveans marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Developers should be aware that `ServicePointManager` is a static class, meaning that any changes made to its properties will have a global effect on all newly created `ServicePoint` objects within the application. For example, modifying a property like `ConnectionLimit` or `Expect100Continue` will impact every new ServicePoint instance. | ||
liveans marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### <xref:System.Net.ServicePointManager> Properties Mapping | ||
|
||
| <xref:System.Net.ServicePointManager> Old API | New API | Notes | | ||
|---------|----------------------|-------| | ||
| `CheckCertificateRevocationList` | <xref:System.Net.Http.SocketsHttpHandler.SslOptions>.CertificateRevocationCheckMode | See TODO: for usage | | ||
| `DefaultConnectionLimit` | <xref:System.Net.Http.SocketsHttpHandler.MaxConnectionsPerServer> | TODO | | ||
| `DnsRefreshTimeout` | No equivalent API | Custom implementation needed | | ||
| `EnableDnsRoundRobin` | No equivalent API | Custom implementation needed | | ||
| `EncryptionPolicy` | No equivalent API | TODO | | ||
| `Expect100Continue` | <xref:System.Net.Http.Headers.HttpRequestHeaders.ExpectContinue> | TODO | | ||
| `MaxServicePointIdleTime` | <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionIdleTimeout> | TODO | | ||
| `MaxServicePoints` | No equivalent API | TODO | | ||
| `ReusePort` | No direct equivalent API | Can be done over <xref:System.Net.Http.SocketsHttpHandler.ConnectCallback>. | | ||
liveans marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| `SecurityProtocol` | <xref:System.Net.Http.SocketsHttpHandler.SslOptions>.EnabledSslProtocols | TODO | | ||
| `ServerCertificateValidationCallback` | <xref:System.Net.Http.SocketsHttpHandler.SslOptions>.RemoteCertificateValidationCallback | Signatures are different need a custom callback | | ||
| `UseNagleAlgorithm` | No direct equivalent API | Can be done over <xref:System.Net.Http.SocketsHttpHandler.ConnectCallback>. | | ||
|
||
### <xref:System.Net.ServicePointManager> Method Mapping | ||
|
||
| <xref:System.Net.ServicePointManager> Old API | New API | Notes | | ||
|---------|----------------------|-------| | ||
| `FindServicePoint` | No equivalent API | TODO | | ||
| `SetTcpKeepAlive` | No direct equivalent API | Can be done over <xref:System.Net.Http.SocketsHttpHandler.ConnectCallback>. | | ||
|
||
### <xref:System.Net.ServicePoint> Properties Mapping | ||
|
||
| <xref:System.Net.ServicePoint> Old API | New API | Notes | | ||
|---------|----------------------|-------| | ||
| `Address` | `HttpRequestMessage.RequestUri` | This is request uri, so basically we can get this from `HttpRequestMessage`. | | ||
liveans marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| `BindIPEndPointDelegate` | No direct equivalent API | Can be done over <xref:System.Net.Http.SocketsHttpHandler.ConnectCallback>. | | ||
| `Certificate` | No direct equivalent API | We can grab this information during `RemoteCertificateValidationCallback`. | | ||
| `ClientCertificate` | No equivalent API | TODO | | ||
| `ConnectionLeaseTimeout` | `SocketsHttpHandler.PooledConnectionLifetime` | Equivalent setting in <xref:System.Net.Http.HttpClient> | | ||
| `ConnectionLimit` | <xref:System.Net.Http.SocketsHttpHandler.MaxConnectionsPerServer> | TODO | | ||
| `ConnectionName` | No equivalent API | TODO | | ||
| `CurrentConnections` | No equivalent API | TODO | | ||
| `Expect100Continue` | <xref:System.Net.Http.Headers.HttpRequestHeaders.ExpectContinue> | TODO | | ||
| `IdleSince` | No equivalent API | TODO | | ||
| `MaxIdleTime` | <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionIdleTimeout> | TODO | | ||
| `ProtocolVersion` | `HttpRequestMessage.Version` | We can get this from `HttpRequestMessage`. | | ||
| `ReceiveBufferSize` | No direct equivalent API | Can be done over <xref:System.Net.Http.SocketsHttpHandler.ConnectCallback>. | | ||
| `SupportsPipelining` | No equivalent API | `HttpClient` doesn't support pipelining. | | ||
| `UseNagleAlgorithm` | No direct equivalent API | Can be done over <xref:System.Net.Http.SocketsHttpHandler.ConnectCallback>. | | ||
|
||
### <xref:System.Net.ServicePoint> Method Mapping | ||
|
||
| <xref:System.Net.ServicePoint> Old API | New API | Notes | | ||
|---------|----------------------|-------| | ||
| `CloseConnectionGroup` | No equivalent | No workaround | | ||
| `SetTcpKeepAlive` | No direct equivalent API | Can be done over <xref:System.Net.Http.SocketsHttpHandler.ConnectCallback>. | | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While mentioning performance, should we mention that it's not just a "nice to have" bump in perf by migrating?
It's really that their existing WebRequest logic's perf is likely going to completely tank once they move to Core since WebRequest is just a minimal compat layer (e.g. no connection reuse in tons of cases).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was actually thinking to add a note or warning for this, to make sure that people who reads this doc will be aware of that
WebRequest
is compat layer on top ofHttpClient
.