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。 伟大的项目!