Reputation: 3324
I am returning a stream of data from a ServiceStack service as follows. Note that I need to do it this way instead of the ways outlined here because I need to perform some cleanup after the data has been written to the output stream.
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
fs.WriteTo(Response.OutputStream);
}
Response.EndRequest();
...cleanup code...
Compression is handled in the other services that return simple DTOs by using a ServiceRunner similar to this answer. However the stream response above never hits that code as the response object in OnAfterExecute
is always null. I am able to manually compress the result inside of the service method as follows, but it requires a lot of setup to determine if and what compression is needed and manually setting up the correct HTTP headers (omitted below).
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...
Is there a way in ServiceStack to handle this compression for me similar to the way it works with the ServiceRunner
?
Upvotes: 2
Views: 457
Reputation: 4816
I'm not exactly sure what you like about the way ServiceStack handles compression within ServiceRunner. Is it because it is global across ServiceStack APIs?
For your example, I think something like below works and meets your need to perform some cleanup after the data has been written to the output stream ...
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...
}
}
Based on comments update of above to add compression using some ServiceStack extensions
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...
}
If you want it within a ServiceRunner something like this should work...
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);
}
Upvotes: 2