Migreringsguide för HttpWebRequest till HttpClient
Den här artikeln syftar till att vägleda utvecklare genom migreringsprocessen från HttpWebRequest, ServicePointoch ServicePointManager till HttpClient. Migreringen är nödvändig på grund av föråldringen av de äldre API:erna och de många fördelar som erbjuds av HttpClient, inklusive förbättrad prestanda, bättre resurshantering och en modernare och flexiblare API-design. Genom att följa de steg som beskrivs i det här dokumentet kommer utvecklare att kunna överföra sina kodbaser smidigt och dra full nytta av de funktioner som tillhandahålls av HttpClient.
Varning
Att migrera från HttpWebRequest
, ServicePoint
och ServicePointManager
till HttpClient
är inte bara en "trevlig att ha" prestandaförbättring. Det är viktigt att förstå att den befintliga WebRequest
logikens prestanda sannolikt kommer att försämras avsevärt när du flyttar till .NET (Core). Det beror på att WebRequest
underhålls som ett minimalt kompatibilitetslager, vilket innebär att det saknar många optimeringar, till exempel återanvändning av anslutningar i flera fall. Därför är övergången till HttpClient
nödvändig för att säkerställa att programmets prestanda och resurshantering uppfyller moderna standarder.
Migrera från HttpWebRequest till HttpClient
Låt oss börja med några exempel:
Enkel GET-begäran med hjälp av HttpWebRequest
Här är ett exempel på hur koden kan se ut:
HttpWebRequest request = WebRequest.CreateHttp(uri);
using WebResponse response = await request.GetResponseAsync();
Enkel GET-begäran med hjälp av HttpClient
Här är ett exempel på hur koden kan se ut:
HttpClient client = new();
using HttpResponseMessage message = await client.GetAsync(uri);
Enkel POST-begäran med HttpWebRequest
Här är ett exempel på hur koden kan se ut:
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();
Enkel POST-begäran med HttpClient
Här är ett exempel på hur koden kan se ut:
HttpClient client = new();
using HttpResponseMessage responseMessage = await client.PostAsync(uri, new StringContent("Hello World!"));
Migreringsguide för HttpWebRequest till HttpClient, SocketsHttpHandler
Migrera ServicePoint(Manager)-användning
Du bör vara medveten om att det ServicePointManager
är en statisk klass, vilket innebär att alla ändringar som görs i dess egenskaper kommer att ha en global effekt på alla nyligen skapade ServicePoint
objekt i programmet. När du till exempel ändrar en egenskap som ConnectionLimit
eller Expect100Continue
påverkar den varje ny ServicePoint-instans.
Varning
I modern .NET HttpClient
tar inte hänsyn till några konfigurationer som angetts för ServicePointManager
.
ServicePointManager egenskapsmappning
Varning
I modern .NET är standardvärdena för UseNagleAlgorithm
egenskaperna och Expect100Continue
inställda på false
. Dessa värden var true
som standard i .NET Framework.
ServicePointManager metodmappning
ServicePointManager Gammalt API | Nytt API | Kommentar |
---|---|---|
FindServicePoint |
Inget motsvarande API | Ingen lösning |
SetTcpKeepAlive |
Inget direkt motsvarande API | Användning av SocketsHttpHandler och ConnectCallback. |
ServicePoint egenskapsmappning
ServicePoint Gammalt API | Nytt API | Kommentar |
---|---|---|
Address |
HttpRequestMessage.RequestUri |
Det här är begärande-URI. Den här informationen finns under HttpRequestMessage . |
BindIPEndPointDelegate |
Inget direkt motsvarande API | Användning av SocketsHttpHandler och ConnectCallback. |
Certificate |
Inget direkt motsvarande API | Den här informationen kan hämtas från RemoteCertificateValidationCallback . Exempel: Hämta certifikat. |
ClientCertificate |
Inget motsvarande API | Exempel: Aktivera ömsesidig autentisering. |
ConnectionLeaseTimeout |
SocketsHttpHandler.PooledConnectionLifetime |
Motsvarande inställning i HttpClient |
ConnectionLimit |
MaxConnectionsPerServer | Exempel: Ställa in SocketsHttpHandler-egenskaper. |
ConnectionName |
Inget motsvarande API | Ingen lösning |
CurrentConnections |
Inget motsvarande API | Se Nätverkstelemetri i .NET. |
Expect100Continue |
ExpectContinue | Exempel: Ange begärandehuvuden. |
IdleSince |
Inget motsvarande API | Ingen lösning |
MaxIdleTime |
PooledConnectionIdleTimeout | Exempel: Ställa in SocketsHttpHandler-egenskaper. |
ProtocolVersion |
HttpRequestMessage.Version |
Exempel: Användning av HttpRequestMessage-egenskaper. |
ReceiveBufferSize |
Inget direkt motsvarande API | Användning av SocketsHttpHandler och ConnectCallback. |
SupportsPipelining |
Inget motsvarande API | HttpClient stöder inte pipelining. |
UseNagleAlgorithm |
Inget direkt motsvarande API | Användning av SocketsHttpHandler och ConnectCallback. |
ServicePoint metodmappning
ServicePoint Gammalt API | Nytt API | Kommentar |
---|---|---|
CloseConnectionGroup |
Ingen motsvarighet | Ingen lösning |
SetTcpKeepAlive |
Inget direkt motsvarande API | Användning av SocketsHttpHandler och ConnectCallback. |
Användning av egenskaper för HttpClient och HttpRequestMessage
När du arbetar med HttpClient i .NET har du åtkomst till en mängd olika egenskaper som gör att du kan konfigurera och anpassa HTTP-begäranden och svar. Att förstå dessa egenskaper kan hjälpa dig att få ut mesta möjliga av HttpClient och se till att ditt program kommunicerar effektivt och säkert med webbtjänster.
Exempel: Användning av HttpRequestMessage-egenskaper
Här är ett exempel på hur du använder HttpClient och HttpRequestMessage tillsammans:
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://example.com"); // Method and RequestUri usage
var request = new HttpRequestMessage() // Alternative way to set RequestUri and Method
{
RequestUri = new Uri("https://example.com"),
Method = HttpMethod.Post
};
request.Headers.Add("Custom-Header", "value");
request.Content = new StringContent("somestring");
using var response = await client.SendAsync(request);
var protocolVersion = response.RequestMessage.Version; // Fetch `ProtocolVersion`.
Exempel: Hämta omdirigerad URI
Här är ett exempel på hur du hämtar omdirigerad URI (samma som HttpWebRequest.Address
):
var client = new HttpClient();
using var response = await client.GetAsync(uri);
var redirectedUri = response.RequestMessage.RequestUri;
Användning av SocketsHttpHandler och ConnectCallback
Med ConnectCallback
egenskapen i SocketsHttpHandler
kan utvecklare anpassa processen för att upprätta en TCP-anslutning. Detta kan vara användbart för scenarier där du behöver styra DNS-matchning eller använda specifika socketalternativ för anslutningen. Med hjälp ConnectCallback
av kan du fånga upp och ändra anslutningsprocessen innan den används av HttpClient
.
Exempel: Binda IP-adress till socket
I den gamla metoden med kan HttpWebRequest
du ha använt anpassad logik för att binda en specifik IP-adress till en socket. Så här kan du uppnå liknande funktioner med hjälp av HttpClient
och ConnectCallback
:
Gammal kod med :HttpWebRequest
HttpWebRequest request = WebRequest.CreateHttp(uri);
request.ServicePoint.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) =>
{
// Bind to a specific IP address
IPAddress localAddress = IPAddress.Parse("192.168.1.100");
return new IPEndPoint(localAddress, 0);
};
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Ny kod som använder HttpClient
och ConnectCallback
:
var handler = new SocketsHttpHandler
{
ConnectCallback = async (context, cancellationToken) =>
{
// Bind to a specific IP address
IPAddress localAddress = IPAddress.Parse("192.168.1.100");
var socket = new Socket(localAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Bind(new IPEndPoint(localAddress, 0));
await socket.ConnectAsync(context.DnsEndPoint, cancellationToken);
return new NetworkStream(socket, ownsSocket: true);
}
catch
{
socket.Dispose();
throw;
}
}
};
var client = new HttpClient(handler);
using var response = await client.GetAsync(uri);
Exempel: Använd specifika socketalternativ
Om du behöver använda specifika socketalternativ, till exempel aktivera TCP keep-alive, kan du använda ConnectCallback
för att konfigurera socketen innan den används av HttpClient
. I själva verket ConnectCallback
är mer flexibelt för att konfigurera socketalternativ.
Gammal kod med :HttpWebRequest
ServicePointManager.ReusePort = true;
HttpWebRequest request = WebRequest.CreateHttp(uri);
request.ServicePoint.SetTcpKeepAlive(true, 60000, 1000);
request.ServicePoint.ReceiveBufferSize = 8192;
request.ServicePoint.UseNagleAlgorithm = false;
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Ny kod som använder HttpClient
och ConnectCallback
:
var handler = new SocketsHttpHandler
{
ConnectCallback = async (context, cancellationToken) =>
{
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
try
{
// Setting TCP Keep Alive
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, 60);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, 1);
// Setting ReceiveBufferSize
socket.ReceiveBufferSize = 8192;
// Enabling ReusePort
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseUnicastPort, true);
// Disabling Nagle Algorithm
socket.NoDelay = true;
await socket.ConnectAsync(context.DnsEndPoint, cancellationToken);
return new NetworkStream(socket, ownsSocket: true);
}
catch
{
socket.Dispose();
throw;
}
}
};
var client = new HttpClient(handler);
using var response = await client.GetAsync(uri);
Exempel: Aktivera DNS-resursallokering
DNS Round Robin är en teknik som används för att distribuera nätverkstrafik över flera servrar genom att rotera genom en lista över IP-adresser som är associerade med ett enda domännamn. Detta bidrar till belastningsutjämning och förbättrad tillgänglighet för tjänster. När du använder HttpClient kan du implementera DNS Round Robin genom att manuellt hantera DNS-matchningen och rotera genom IP-adresserna med egenskapen ConnectCallback för SocketsHttpHandler.
Om du vill aktivera DNS Round Robin med HttpClient kan du använda egenskapen ConnectCallback för att manuellt matcha DNS-posterna och rotera genom IP-adresserna. Här är ett exempel för HttpWebRequest
och HttpClient
:
Gammal kod med :HttpWebRequest
ServicePointManager.DnsRefreshTimeout = 60000;
ServicePointManager.EnableDnsRoundRobin = true;
HttpWebRequest request = WebRequest.CreateHttp(uri);
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
I det äldre HttpWebRequest
API:et var det enkelt att aktivera DNS Round Robin på grund av dess inbyggda stöd för den här funktionen. Det nyare HttpClient
API:et tillhandahåller dock inte samma inbyggda funktioner. Trots detta kan du uppnå liknande beteende genom att implementera en DnsRoundRobinConnector
som manuellt roterar genom DE IP-adresser som returneras av DNS-matchning.
Ny kod med :HttpClient
// This is available as NuGet Package: https://www.nuget.org/packages/DnsRoundRobin/
// The original source code can be found also here: https://github.com/MihaZupan/DnsRoundRobin
public sealed class DnsRoundRobinConnector : IDisposable
Du hittar implementeringen av DnsRoundRobinConnector
här.
DnsRoundRobinConnector
Användning:
private static readonly DnsRoundRobinConnector s_roundRobinConnector = new(
dnsRefreshInterval: TimeSpan.FromSeconds(10),
endpointConnectTimeout: TimeSpan.FromSeconds(5));
static async Task DnsRoundRobinConnectAsync()
{
var handler = new SocketsHttpHandler
{
ConnectCallback = async (context, cancellation) =>
{
Socket socket = await DnsRoundRobinConnector.Shared.ConnectAsync(context.DnsEndPoint, cancellation);
// Or you can create and use your custom DnsRoundRobinConnector instance
// Socket socket = await s_roundRobinConnector.ConnectAsync(context.DnsEndPoint, cancellation);
return new NetworkStream(socket, ownsSocket: true);
}
};
var client = new HttpClient(handler);
HttpResponseMessage response = await client.GetAsync(Uri);
}
Exempel: Ange egenskaper för SocketsHttpHandler
SocketsHttpHandler är en kraftfull och flexibel hanterare i .NET som tillhandahåller avancerade konfigurationsalternativ för hantering av HTTP-anslutningar. Genom att ange olika egenskaper för SocketsHttpHandler kan du finjustera HTTP-klientens beteende för att uppfylla specifika krav, till exempel prestandaoptimering, säkerhetsförbättringar och anpassad anslutningshantering.
Här är ett exempel på hur du konfigurerar SocketsHttpHandler med olika egenskaper och använder det med HttpClient:
var cookieContainer = new CookieContainer();
cookieContainer.Add(new Cookie("cookieName", "cookieValue"));
var handler = new SocketsHttpHandler
{
AllowAutoRedirect = true,
AutomaticDecompression = DecompressionMethods.All,
Expect100ContinueTimeout = TimeSpan.FromSeconds(1),
CookieContainer = cookieContainer,
Credentials = new NetworkCredential("user", "pass"),
MaxAutomaticRedirections = 10,
MaxResponseHeadersLength = 1,
Proxy = new WebProxy("http://proxyserver:8080"), // Don't forget to set UseProxy
UseProxy = true,
};
var client = new HttpClient(handler);
using var response = await client.GetAsync(uri);
Exempel: Ändra personifieringNivå
Den här funktionen är specifik för vissa plattformar och är något inaktuell. Om du behöver en lösning kan du läsa det här avsnittet i koden.
Användning av certifikat och TLS-relaterade egenskaper i HttpClient
När du arbetar med HttpClient
kan du behöva hantera klientcertifikat i olika syften, till exempel anpassad validering av servercertifikat eller hämtning av servercertifikatet. HttpClient
innehåller flera egenskaper och alternativ för att hantera certifikat effektivt.
Exempel: Kontrollera listan över återkallade certifikat med SocketsHttpHandler
Med CheckCertificateRevocationList
egenskapen i SocketsHttpHandler.SslOptions
kan utvecklare aktivera eller inaktivera kontrollen av listor över återkallade certifikat (CRL) under handskakning av SSL/TLS. Om du aktiverar den här egenskapen ser du till att klienten verifierar om serverns certifikat har återkallats, vilket förbättrar säkerheten för anslutningen.
Gammal kod med :HttpWebRequest
ServicePointManager.CheckCertificateRevocationList = true;
HttpWebRequest request = WebRequest.CreateHttp(uri);
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Ny kod med :HttpClient
bool checkCertificateRevocationList = true;
var handler = new SocketsHttpHandler
{
SslOptions =
{
CertificateRevocationCheckMode = checkCertificateRevocationList ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
}
};
var client = new HttpClient(handler);
using var response = await client.GetAsync(uri);
Exempel: Hämta certifikat
Om du vill hämta certifikatet RemoteCertificateValidationCallback
från i HttpClient
kan du använda ServerCertificateCustomValidationCallback
egenskapen HttpClientHandler
eller SocketsHttpHandler.SslOptions
. Med det här återanropet kan du inspektera serverns certifikat under handskakningen SSL/TLS.
Gammal kod med :HttpWebRequest
HttpWebRequest request = WebRequest.CreateHttp(uri);
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
X509Certificate? serverCertificate = request.ServicePoint.Certificate;
Ny kod med :HttpClient
X509Certificate? serverCertificate = null;
var handler = new SocketsHttpHandler
{
SslOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
serverCertificate = certificate;
// Leave the validation as-is.
return sslPolicyErrors == SslPolicyErrors.None;
}
}
};
var client = new HttpClient(handler);
using var response = await client.GetAsync("https://example.com");
Exempel: Aktivera ömsesidig autentisering
Ömsesidig autentisering, även kallat dubbelriktad SSL- eller klientcertifikatautentisering, är en säkerhetsprocess där både klienten och servern autentiserar varandra. Detta säkerställer att båda parter är de som de påstår sig vara, vilket ger ytterligare ett säkerhetslager för känslig kommunikation. I HttpClient
kan du aktivera ömsesidig autentisering genom att HttpClientHandler
konfigurera eller SocketsHttpHandler
inkludera klientcertifikatet och verifiera serverns certifikat.
Följ dessa steg för att aktivera ömsesidig autentisering:
- Läs in klientcertifikatet.
- Konfigurera HttpClientHandler eller SocketsHttpHandler så att det innehåller klientcertifikatet.
- Konfigurera servercertifikatets valideringsåteranrop om anpassad validering behövs.
Här är ett exempel med SocketsHttpHandler:
var handler = new SocketsHttpHandler
{
SslOptions = new SslClientAuthenticationOptions
{
ClientCertificates = new X509CertificateCollection
{
// Load the client certificate from a file
new X509Certificate2("path_to_certificate.pfx", "certificate_password")
},
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
// Custom validation logic for the server certificate
return sslPolicyErrors == SslPolicyErrors.None;
}
}
};
var client = new HttpClient(handler);
using var response = await client.GetAsync(uri);
Användning av rubrikegenskaper
Rubriker spelar en avgörande roll i HTTP-kommunikation och tillhandahåller viktiga metadata om begäran och svar. När du arbetar med HttpClient
i .NET kan du ange och hantera olika rubrikegenskaper för att styra beteendet för dina HTTP-begäranden och svar. Genom att förstå hur du använder dessa rubrikegenskaper effektivt kan du se till att ditt program kommunicerar effektivt och säkert med webbtjänster.
Ange begärandehuvuden
Begärandehuvuden används för att ge ytterligare information till servern om den begäran som görs. Vanliga användningsfall är att ange innehållstyp, ange autentiseringstoken och lägga till anpassade rubriker. Du kan ange begärandehuvuden DefaultRequestHeaders
med egenskapen HttpClient
eller egenskapen Headers för HttpRequestMessage
.
Exempel: Ange anpassade begärandehuvuden
Ange standardrubriker för anpassade begäranden i HttpClient
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Custom-Header", "value");
Ange anpassade begärandehuvuden i HttpRequestMessage
var request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("Custom-Header", "value");
Exempel: Ange vanliga begärandehuvuden
När du arbetar med HttpRequestMessage
i .NET är det viktigt att ange vanliga begärandehuvuden för att ge ytterligare information till servern om den begäran som görs. Dessa rubriker kan innehålla autentiseringstoken med mera. Korrekt konfiguration av dessa huvuden säkerställer att dina HTTP-begäranden bearbetas korrekt av servern.
En omfattande lista över vanliga egenskaper som är tillgängliga i finns i HttpRequestHeadersEgenskaper.
Om du vill ange vanliga begärandehuvuden Headers
i HttpRequestMessage
kan du använda -egenskapen för HttpRequestMessage
objektet. Den här egenskapen ger åtkomst till HttpRequestHeaders
samlingen, där du kan lägga till eller ändra rubriker efter behov.
Ange vanliga standardrubriker för begäranden i HttpClient
using System.Net.Http.Headers;
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "token");
Ange vanliga begärandehuvuden i HttpRequestMessage
using System.Net.Http.Headers;
var request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "token");
Exempel: Ange innehållsrubriker
Innehållshuvuden används för att ge ytterligare information om brödtexten i en HTTP-begäran eller ett HTTP-svar. När du arbetar med HttpClient
i .NET kan du ange innehållshuvuden för att ange medietyp, kodning och andra metadata som är relaterade till innehållet som skickas eller tas emot. Korrekt konfiguration av innehållshuvuden säkerställer att servern och klienten kan tolka och bearbeta innehållet korrekt.
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, uri);
// Create the content and set the content headers
var jsonData = "{\"key\":\"value\"}";
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
// The following headers are set automatically by `StringContent`. If you wish to override their values, you can do it like so:
// content.Headers.ContentType = new MediaTypeHeaderValue("application/json; charset=utf-8");
// content.Headers.ContentLength = Encoding.UTF8.GetByteCount(jsonData);
// Assign the content to the request
request.Content = content;
using var response = await client.SendAsync(request);
Exempel: Ange MaximumErrorResponseLength i HttpClient
Med MaximumErrorResponseLength
användningen kan utvecklare ange den maximala längden på det felsvarsinnehåll som hanteraren buffrar. Detta är användbart för att kontrollera mängden data som läss och lagras i minnet när ett felsvar tas emot från servern. Med den här tekniken kan du förhindra överdriven minnesanvändning och förbättra programmets prestanda vid hantering av stora felsvar.
Det finns några sätt att göra det på, vi undersöker TruncatedReadStream
tekniken i det här exemplet:
internal sealed class TruncatedReadStream(Stream innerStream, long maxSize) : Stream
{
private long _maxRemainingLength = maxSize;
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length => throw new NotSupportedException();
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
public override void Flush() => throw new NotSupportedException();
public override int Read(byte[] buffer, int offset, int count)
{
return Read(new Span<byte>(buffer, offset, count));
}
public override int Read(Span<byte> buffer)
{
int readBytes = innerStream.Read(buffer.Slice(0, (int)Math.Min(buffer.Length, _maxRemainingLength)));
_maxRemainingLength -= readBytes;
return readBytes;
}
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return ReadAsync(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
}
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
{
int readBytes = await innerStream.ReadAsync(buffer.Slice(0, (int)Math.Min(buffer.Length, _maxRemainingLength)), cancellationToken)
.ConfigureAwait(false);
_maxRemainingLength -= readBytes;
return readBytes;
}
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
public override ValueTask DisposeAsync() => innerStream.DisposeAsync();
protected override void Dispose(bool disposing)
{
if (disposing)
{
innerStream.Dispose();
}
}
}
Och användningsexempel på TruncatedReadStream
:
int maxErrorResponseLength = 1 * 1024; // 1 KB
HttpClient client = new HttpClient();
using HttpResponseMessage response = await client.GetAsync(Uri);
if (response.Content is not null)
{
Stream responseReadStream = await response.Content.ReadAsStreamAsync();
// If MaxErrorResponseLength is set and the response status code is an error code, then wrap the response stream in a TruncatedReadStream
if (maxErrorResponseLength >= 0 && !response.IsSuccessStatusCode)
{
responseReadStream = new TruncatedReadStream(responseReadStream, maxErrorResponseLength);
}
// Read the response stream
Memory<byte> buffer = new byte[1024];
int readValue = await responseReadStream.ReadAsync(buffer);
}
Exempel: Använd CachePolicy-huvuden
Varning
HttpClient
har inte inbyggd logik för att cachelagrar svar. Det finns ingen annan lösning än att implementera all cachelagring själv. Det går inte att cachelagra genom att ange rubrikerna.
När du migrerar från HttpWebRequest
till HttpClient
är det viktigt att hantera cacherelaterade rubriker som pragma
och cache-control
. Dessa rubriker styr hur svar cachelagras och hämtas, vilket säkerställer att ditt program fungerar som förväntat när det gäller prestanda och datas färskhet.
I HttpWebRequest
kan du ha använt CachePolicy
egenskapen för att ange dessa rubriker. I måste du dock HttpClient
ange dessa rubriker manuellt på begäran.
Gammal kod med :HttpWebRequest
HttpWebRequest request = WebRequest.CreateHttp(uri);
request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
I det äldre HttpWebRequest
API:et var det enkelt att tillämpa CachePolicy
på grund av dess inbyggda stöd för den här funktionen. Det nyare HttpClient
API:et tillhandahåller dock inte samma inbyggda funktioner. Trots detta kan du uppnå liknande beteende genom att implementera en AddCacheControlHeaders
som manuellt lägger till cacherelaterade huvuden.
Ny kod med :HttpClient
public static class CachePolicy
{
public static void AddCacheControlHeaders(HttpRequestMessage request, RequestCachePolicy policy)
Du hittar implementeringen av AddCacheControlHeaders
här.
AddCacheControlHeaders
Användning:
static async Task AddCacheControlHeaders()
{
HttpClient client = new HttpClient();
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, Uri);
CachePolicy.AddCacheControlHeaders(requestMessage, new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore));
HttpResponseMessage response = await client.SendAsync(requestMessage);
}
Användning av buffringsegenskaper
När du migrerar från HttpWebRequest till HttpClient
är det viktigt att förstå skillnaderna i hur dessa två API:er hanterar buffring.
Gammal kod med :HttpWebRequest
I HttpWebRequest
har du direkt kontroll över buffringsegenskaper via AllowWriteStreamBuffering
egenskaperna och AllowReadStreamBuffering
. Dessa egenskaper aktiverar eller inaktiverar buffring av data som skickas till och tas emot från servern.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AllowReadStreamBuffering = true; // Default is `false`.
request.AllowWriteStreamBuffering = false; // Default is `true`.
Ny kod med :HttpClient
I HttpClient
finns det inga direkta motsvarigheter till AllowWriteStreamBuffering
egenskaperna och AllowReadStreamBuffering
.
HttpClient buffrar inte begärandeorgan på egen hand, utan delegerar i stället ansvaret till de HttpContent
använda. Innehåll som StringContent
eller ByteArrayContent
är logiskt redan buffrade i minnet, medan användning StreamContent
inte medför någon buffring som standard. Om du vill framtvinga att innehållet buffrats kan du anropa HttpContent.LoadIntoBufferAsync
innan du skickar begäran. Här är ett exempel:
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
request.Content = new StreamContent(yourStream);
await request.Content.LoadIntoBufferAsync();
HttpResponseMessage response = await client.SendAsync(request);
I HttpClient
läsbuffertning är aktiverat som standard. För att undvika det kan du ange HttpCompletionOption.ResponseHeadersRead
flaggan eller använda hjälpen GetStreamAsync
.
HttpClient client = new HttpClient();
using HttpResponseMessage response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
await using Stream responseStream = await response.Content.ReadAsStreamAsync();
// Or simply
await using Stream responseStream = await client.GetStreamAsync(uri);