ServiceStack supporta le risposte binarie?

C’è qualche meccanismo nei servizi di ServiceStack per restituire lo streaming / grandi dati binari? Il supporto MTOM di WCF è scomodo ma efficace nel restituire grandi quantità di dati senza overhead di conversione del testo.

Da una vista a volo d’ uccello, ServiceStack può restituire:

  • Qualsiasi object DTO -> serializzato su Response ContentType
  • HttpResult, HttpError, CompressedResult (IHttpResult) per risposta HTTP personalizzata

I seguenti tipi non vengono convertiti e vengono scritti direttamente sul stream di risposta:

  • Stringa
  • ruscello
  • IStreamWriter
  • byte [] – con il tipo di contenuto application/octet-stream .

Dettagli

Oltre a restituire semplici oggetti C #, ServiceStack consente di restituire qualsiasi stream o IStreamWriter (che è un po ‘più flessibile su come scrivere nel stream di risposta):

 public interface IStreamWriter { void WriteTo(Stream stream); } 

Entrambi consentono di scrivere direttamente su Response Outputtream senza alcun overhead di conversione aggiuntivo.

Se si desidera personalizzare le intestazioni HTTP allo stesso tempo, è necessario implementare IHasOptions in cui qualsiasi voce del dizionario viene scritta nei Response HttpHeaders.

 public interface IHasOptions { IDictionary Options { get; } } 

Oltre a ciò, IHttpResult consente un controllo ancora più preciso dell’output HTTP in cui è ansible fornire un codice di stato di risposta Http personalizzato. È ansible fare riferimento all’implementazione dell’object HttpResult per un’implementazione realistica di queste interfacce precedenti.

Adoro lo stack di servizio, questo litle code è stato sufficiente per restituire un report Excel dal stream di memoria

 public class ExcelFileResult : IHasOptions, IStreamWriter { private readonly Stream _responseStream; public IDictionary Options { get; private set; } public ExcelFileResult(Stream responseStream) { _responseStream = responseStream; Options = new Dictionary { {"Content-Type", "application/octet-stream"}, {"Content-Disposition", "attachment; filename=\"report.xls\";"} }; } public void WriteTo(Stream responseStream) { if (_responseStream == null) return; _responseStream.WriteTo(responseStream); responseStream.Flush(); } } 

Avevo un requisito simile che mi richiedeva anche di tenere traccia dell’avanzamento del download del file di streaming. L’ho fatto più o meno così:

lato server :

servizio:

 public object Get(FooRequest request) { var stream = ...//some Stream return new StreamedResult(stream); } 

Classe StreamedResult:

 public class StreamedResult : IHasOptions, IStreamWriter { public IDictionary Options { get; private set; } Stream _responseStream; public StreamedResult(Stream responseStream) { _responseStream = responseStream; long length = -1; try { length = _responseStream.Length; } catch (NotSupportedException) { } Options = new Dictionary { {"Content-Type", "application/octet-stream"}, { "X-Api-Length", length.ToString() } }; } public void WriteTo(Stream responseStream) { if (_responseStream == null) return; using (_responseStream) { _responseStream.WriteTo(responseStream); responseStream.Flush(); } } } 

lato client :

 string path = Path.GetTempFileName();//in reality, wrap this in try... so as not to leave hanging tmp files var response = client.Get("/foo/bar"); long length; if (!long.TryParse(response.GetResponseHeader("X-Api-Length"), out length)) length = -1; using (var fs = System.IO.File.OpenWrite(path)) fs.CopyFrom(response.GetResponseStream(), new CopyFromArguments(new ProgressChange((x, y) => { Console.WriteLine(">> {0} {1}".Fmt(x, y)); }), TimeSpan.FromMilliseconds(100), length)); 

Il metodo di estensione “CopyFrom” è stato preso in prestito direttamente dal file di codice sorgente “StreamHelper.cs” in questo progetto qui: Copia un stream con report di avanzamento (Kudos a Henning Dieterichs)

E complimenti a mythz e qualsiasi contributore a ServiceStack. Ottimo progetto!