ServiceStack 并返回一个流

Posted

技术标签:

【中文标题】ServiceStack 并返回一个流【英文标题】:ServiceStack and returning a stream 【发布时间】:2012-04-19 21:44:36 【问题描述】:

我刚刚开始使用 ServiceStack,这是一个很棒的库。

但是,我有一个业务需求,我们必须返回 xml 和 json,其中 xml 必须采用特定格式。

例如,我们现有的客户希望使用以下格式的 xml:

<service name="service1" type="audio" .../>

所以基本上是一堆属性。

我知道 ServiceStack 使用 DTO 的概念并使用返回 xml 元素的 DataContractSerializer,而不是上面带有 xml 属性的表单。

我仍然想对请求使用 DTO(在 Accept 标头中传入 application/xml 或 application/json),然后我可以创建自己的 xml 字符串或 json 字符串,然后将它们返回为:

string result = "....xml or json string...";
return new MemoryStream(Encoding.UTF8.GetBytes(result));

结果字符串可以是 xml 字符串或 json 字符串。

我在 fiddler 中注意到响应 Content-Type 为 text/html

我使用的方法是否违反了任何 REST 原则?当前的 Content-Type (text/html) 会有问题吗?

如果我确实使用这种方法,它确实可以解决业务需求。

编辑

我发现我可以将 httpResult 返回为:

return new HttpResult(
         new MemoryStream(Encoding.UTF8.GetBytes(result)), "application/xml");

它给出了正确的内容类型。

那么,这是正确的方式吗?如果我沿着这条路走,我会遇到问题吗?

【问题讨论】:

【参考方案1】:

是的,返回 IHttpResult 将允许您根据需要控制确切的负载、Content-Type 和其他 HTTP 标头。

此外,您不限于返回流,即您可以使用 HttpResult 返回具有不同 Content-Type 的 xml 字符串。

这里有一些链接可以更好地展示 ServiceStack 返回类型的可能性:

How ServiceStack supports plain C# string, binary, stream, IStreamWriter, etc return types An example of using CORS to set global or per-service custom HTTP Headers Different ways of returning an Image from a ServiceStack service Multiple options for returning HTML

您还可以使用 FileInfo 对象返回静态文件,并带有一个可选参数以将文件作为附件返回,这将提示用户下载文件而不是尝试在浏览器中查看:

return new HttpResult(new FileInfo("~/static-response.xml"), asAttachment:true);

【讨论】:

返回字符串而不是流会有什么好处吗? 不,两者都直接写入 ASP.NET 的 HttpResponse OutputStream。因此,使用 MemoryStream(如果您已经在内存中拥有 String)会增加额外的开销。当您想要流式传输输出时返回一个字符串是有意义的(即避免将整个响应加载到内存中) 我花了更长的时间才发现我希望在这里提到的一件事:使用在 client 端返回流的 ServiceStack 服务,可以绕过通过调用 HttpWebReponse 类型的 Get,客户端的反序列化器。这让您可以使用 response.GetResponseHeader(string) 和 reponse.GetResponseStream() 获取标题和底层流 关于我上面的评论,我在这里发布了更详细的答案:***.com/questions/14134667/…

以上是关于ServiceStack 并返回一个流的主要内容,如果未能解决你的问题,请参考以下文章

ServiceStack CORS 功能

解析 ServiceStack 服务并定义内容类型

ServiceStack v4 中服务的 Db 为空

C# Redis分布式锁(基于ServiceStack.Redis)

Ionic不能在Safari和iOS 11上使用ServiceStack Client

具有模式的 ServiceStack IRedisClient ScanAllKeys 未按预期返回结果 (ServiceStack 5.7.0)