ServiceStack流压缩

时间:2013-09-16 20:09:26

标签: c# compression servicestack

我从ServiceStack服务返回一个数据流,如下所示。请注意,我需要这样做而不是概述here的方式,因为我需要在将数据写入输出流后执行一些清理。

using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
    fs.WriteTo(Response.OutputStream);
}
Response.EndRequest();
...cleanup code...

通过使用类似于this answer的ServiceRunner,在其他返回简单DTO的服务中处理压缩。但是,上面的流响应永远不会命中该代码,因为OnAfterExecute中的响应对象始终为null。我可以按如下方式手动压缩服务方法内部的结果,但需要进行大量设置以确定是否需要压缩以及手动设置正确的HTTP标头(下面省略)。

var outStream = new MemoryStream();
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (var tinyStream = new GZipStream(outStream, CompressionMode.Compress))
{
    fs.CopyTo(tinyStream);
    outStream.WriteTo(Response.OutputStream);
}
Response.EndRequest();
...cleanup code...

ServiceStack中是否有办法为我处理此压缩,类似于ServiceRunner的处理方式?

1 个答案:

答案 0 :(得分:2)

我不完全确定您对ServiceStack在ServiceRunner中处理压缩的方式的喜好。是因为它跨ServiceStack API是全局的吗?

对于您的示例,我认为类似下面的内容可以工作,并且在将数据写入输出流后满足您执行某些清理的需要...

public class FStreamService : Service
{
    public object Get(FStream request)
    {
        var filePath = @"c:\test.xml";
        var compressFileResult = new CompressedFileResult(filePath); //CompressedResult in ServiceStack.Common.Web.CompressedFileResult
        compressFileResult.WriteTo(Response.OutputStream);
        Response.EndRequest();
        //  ...cleanup code...
    }
}

根据上述评论更新,使用某些ServiceStack扩展程序添加压缩

public object Get(FStream request)
{
    var filePath = @"c:\test.xml";
    using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        var compressedBtyes = fs.ToUtf8String().Compress(this.RequestContext.CompressionType);
        new CompressedResult(compressedBtyes).WriteTo(Response.OutputStream);           
    }
    Response.EndRequest();
        //  ...cleanup code...
}

如果你想在ServiceRunner中使用这样的东西应该有效......

public override object OnAfterExecute(IRequestContext requestContext, object response)
{
    var resp = requestContext.Get<IHttpResponse>();
    response = requestContext.ToOptimizedResult(requestContext.Get<IHttpResponse>().OutputStream);       

    return base.OnAfterExecute(requestContext, response);
}

<击>