2017-10-09 7 views
2

J'envoie une requête qui peut être significativement grande (~ 1Mb) et je vois un grand délai entre quand je fais la demande et quand le noyau asp.net enregistre qu'il traite la demande. Je pense que je peux réduire cette fois en compressant la demande à asp en utilisant gzip.Quel est le meilleur moyen de compresser une requête sur le site asp.net core 2 en utilisant HttpClient?

Ci-dessous est le moyen assez simple que je fais des demandes sans compression. Quelle est la bonne façon d'implémenter la compression de requête Gzip sur le côté demandeur, et une fois que je l'implémente sur le client, que dois-je faire pour le côté serveur?

using (HttpResponseMessage response = client.PostAsync("Controller/Action", httpContent).Result) 
{ 
    if (response.StatusCode != System.Net.HttpStatusCode.OK) 
    { 

     throw new Exception(string.Format("Invalid responsecode for http request response {0}: {1}", response.StatusCode, response.ReasonPhrase)); 
    } 
} 

Répondre

3

donc je l'ai eu à travailler avec le middleware simple sur le côté serveur et pas trop de travail sur le côté client. J'ai utilisé le compressedContent.cs du projet WebAPIContrib github, comme Rex l'a suggéré dans les commentaires de sa réponse, et fait la demande comme indiqué ci-dessous. L'exception entière de lancement si pas OK est parce que j'utilise Polly enroulé autour de ma demande avec une politique Retry et wait.

côté client:

using (var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json")) 
using (var compressedContent = new CompressedContent(httpContent, "gzip")) 
using (HttpResponseMessage response = client.PostAsync("Controller/Action", compressedContent).Result) 
{ 
    if (response.StatusCode != System.Net.HttpStatusCode.OK) 
    { 
     throw new Exception(string.Format("Invalid responsecode for http request response {0}: {1}", response.StatusCode, response.ReasonPhrase)); 
    } 
} 

Ensuite, sur le côté serveur que je crée un simple morceau de middleware qui enveloppé le flux de corps de la demande avec le flux Gzip, je suis assez sûr que vous avez besoin de mettre le middleware avant application. UseMvc() dans la fonction configure (j'utilise toujours le style de démarrage ASPcore 1).

public class GzipRequestMiddleware 
{ 
    private readonly RequestDelegate next; 
    private const string ContentEncodingHeader = "Content-Encoding"; 
    private const string ContentEncodingGzip = "gzip"; 
    private const string ContentEncodingDeflate = "deflate"; 

    public GzipRequestMiddleware(RequestDelegate next) 
    { 
     this.next = next ?? throw new ArgumentNullException(nameof(next)); 
    } 


    public async Task Invoke(HttpContext context) 
    { 
     if (context.Request.Headers.Keys.Contains(ContentEncodingHeader) && (context.Request.Headers[ContentEncodingHeader] == ContentEncodingGzip || context.Request.Headers[ContentEncodingHeader] == ContentEncodingDeflate)) 
     { 
      var contentEncoding = context.Request.Headers[ContentEncodingHeader]; 
      var decompressor = contentEncoding == ContentEncodingGzip ? (Stream)new GZipStream(context.Request.Body, CompressionMode.Decompress, true) : (Stream)new DeflateStream(context.Request.Body, CompressionMode.Decompress, true); 
      context.Request.Body = decompressor; 
     } 
     await next(context); 
    } 
} 
1

Vous devrez peut-être activer la compression comme indiqué ci-dessous

var handler = new HttpClientHandler(); 
if (handler.SupportsAutomaticDecompression) 
{ 
    handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; 
} 

var client = new HttpClient(handler); 

MSDN Référence: Using automatic decompression with HttpClient

+1

Un lien de référence msdn serait parfait –

+0

https://blogs.msdn.microsoft.com/dotnet/2013/06/06/portable-compression-and-httpclient-working-together/ – Rex

+0

Peut-être que je suis manquant quelque chose mais qui semble ne traiter que la décompression de la réponse et ne pas demander la compression, non? – Theyouthis