ServiceStack是否支持二进制响应?

ServiceStack服务中是否有返回stream/大二进制数据的机制? WCF的MTOM支持在返回大量数据时没有文本转换开销,但是非常有效。

从一个鸟瞰视图ServiceStack可以返回任何:

  • 任何DTO对象 – >序列化为Response ContentType
  • HttpResult,HttpError,CompressedResult(IHttpResult)用于定制HTTP响应

以下types不会被转换并直接写入响应stream:

  • stream
  • IStreamWriter
  • 字节[] – 与application/octet-stream内容types。

细节

除了返回纯C#对象之外,ServiceStack还允许您返回任何Stream或IStreamWriter(对于如何写入响应stream,这更灵活一些):

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

两者都允许您直接写入Response OutputStream,而不会有任何额外的转换开销。

如果你想在同一时间自定义HTTP标题,你只需要实现IHasOptions任何字典条目被写入响应HttpHeaders。

 public interface IHasOptions { IDictionary<string, string> Options { get; } } 

除此之外,IHttpResult还允许对HTTP输出进行更细粒度的控制,您可以在其中提供自定义的Http Response状态代码。 您可以参考HttpResult对象的实现,以获得上述接口的实际实现。

我喜欢服务栈,这个小小的代码足以从内存stream中返回Excel报告

 public class ExcelFileResult : IHasOptions, IStreamWriter { private readonly Stream _responseStream; public IDictionary<string, string> Options { get; private set; } public ExcelFileResult(Stream responseStream) { _responseStream = responseStream; Options = new Dictionary<string, string> { {"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(); } } 

我也有类似的要求,这也要求我跟踪stream文件下载的进度。 我大致是这样做的:

服务器端

服务:

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

StreamedResult类:

 public class StreamedResult : IHasOptions, IStreamWriter { public IDictionary<string, string> Options { get; private set; } Stream _responseStream; public StreamedResult(Stream responseStream) { _responseStream = responseStream; long length = -1; try { length = _responseStream.Length; } catch (NotSupportedException) { } Options = new Dictionary<string, string> { {"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(); } } } 

客户端

 string path = Path.GetTempFileName();//in reality, wrap this in try... so as not to leave hanging tmp files var response = client.Get<HttpWebResponse>("/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)); 

“CopyFrom”扩展方法是直接从这个项目的源代码文件“StreamHelper.cs”中借用的: 复制一个包含进度报告的Stream (赞美Henning Dieterichs)

并赞美神话和任何贡献者的ServiceStack。 伟大的项目!