2015-06-04 20 views
7

Ho bisogno di recuperare la lunghezza del corpo della risposta.Come recuperare la lunghezza del corpo della risposta corrente?

Quando guardo https://github.com/aspnet/HttpAbstractions/wiki/Rolling-Notes-Response-Stream-Contract si dice che:

Stream.Position {get} e {get Stream.Length} tornare byte cumulativi scritte

questo è esattamente quello che mi serve, ma httpContext.Response.Body.Length solleva il NotSupportedException e dice "Il flusso non è ricercabile".

Devo utilizzare un flusso delegante per contare i byte su ciascuna scrittura?

+2

Curioso, qual è lo scenario in cui ti serve? Probabilmente un modo per ottenere queste informazioni è registrarsi per il callback di "OnSendingHeaders" sulla risposta corrente. Esempio: 'httpContext.Response.OnSendingHeaders (callback: (stato) => {var length: (HttpContext) state.ContentLength;}, stato: httpContext)'. –

+1

Penso di aver perso l'ultima riga del post ... certo, anche quello funzionerebbe ... potresti scrivere un middleware che è registrato molto presto nella pipeline e avvolge il corpo della risposta con un flusso delegante ... –

+1

@ KiranChalla I richiede la lunghezza del contenuto per il conteggio della larghezza di banda consumata. Quando la quota viene superata, le richieste future verranno bloccate/rallentate. Il callback 'OnSendingHeaders' non funziona: la proprietà' ContentLength' è impostata su 'null'. Questo è lo stesso con il callback 'OnResponseCompleted'. – ycrumeyrolle

risposta

2

Suppongo che stiate cercando di ottenere ContentLength da un middleware?

Ecco un esempio di Middleware. Dovrebbe essere aggiunto alla pipeline (startup.cs) prima di ogni risposta che generi middleware come useMVC o useStaticFiles.

public class ContentLengthMiddleware 
{ 
    RequestDelegate _next; 

    public ContentLengthMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     using (var buffer = new MemoryStream()) 
     { 
      var request = context.Request; 
      var response = context.Response; 

      var bodyStream = response.Body; 
      response.Body = buffer; 

      await _next(context); 
      Debug.WriteLine($"{request.Path} ({response.ContentType}) Content-Length: {response.ContentLength ?? buffer.Length}"); 
      buffer.Position = 0; 
      await buffer.CopyToAsync(bodyStream); 
     } 
    } 
} 

Per ragioni che vanno oltre la mia comprensione al ritorno file statici (png, JS, etc) il corpo della risposta sarà vuota tuttavia ContentLength è impostato è per questo che ho usato il response.ContentLength ?? buffer.Length.

(Nota per la mod: mi dispiace per la risposta duplicata a due domande.L'altra risposta è stata inviata in modo errato, troppe schede aperte. L'ho cancellata e ho ripubblicato la risposta qui).

+1

Lo svantaggio di questa soluzione è l'uso di un 'MemoryStream'. Consuma inutilmente la memoria. – ycrumeyrolle

+1

Ho eseguito l'override di uno stream e contiamo ad ogni scrittura in questo modo: public override void Write (byte [] buffer, int offset, int count) { _tracker.ContentLength + = count - offset; _inner.Write (buffer, offset, count); } – ycrumeyrolle

Problemi correlati