我目前正在将我的几个MVC3控制器迁移到MVC4 Api控制器上。我通过继承ActionFilterAttribute
和重写OnActionExecutiong
方法,实现了MVC3控制器获取方法响应的压缩机制。经过一番研究后,我发现我需要使用System.Web.HttpFilters
中的ActionFilterMethod
。如果有人能分享一段示例代码,让我开始使用GZip压缩HTTP响应,那就太好了
发布于 2012-05-04 17:21:39
最简单的方法是直接在IIS级别执行enable compression。
如果您希望在应用程序级别执行此操作,则可以编写自定义委托消息处理程序,如following post中所示
public class CompressHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) =>
{
HttpResponseMessage response = responseToCompleteTask.Result;
if (response.RequestMessage.Headers.AcceptEncoding != null)
{
string encodingType = response.RequestMessage.Headers.AcceptEncoding.First().Value;
response.Content = new CompressedContent(response.Content, encodingType);
}
return response;
},
TaskContinuationOptions.OnlyOnRanToCompletion);
}
}
public class CompressedContent : HttpContent
{
private HttpContent originalContent;
private string encodingType;
public CompressedContent(HttpContent content, string encodingType)
{
if (content == null)
{
throw new ArgumentNullException("content");
}
if (encodingType == null)
{
throw new ArgumentNullException("encodingType");
}
originalContent = content;
this.encodingType = encodingType.ToLowerInvariant();
if (this.encodingType != "gzip" && this.encodingType != "deflate")
{
throw new InvalidOperationException(string.Format("Encoding '{0}' is not supported. Only supports gzip or deflate encoding.", this.encodingType));
}
// copy the headers from the original content
foreach (KeyValuePair<string, IEnumerable<string>> header in originalContent.Headers)
{
this.Headers.AddWithoutValidation(header.Key, header.Value);
}
this.Headers.ContentEncoding.Add(encodingType);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
Stream compressedStream = null;
if (encodingType == "gzip")
{
compressedStream = new GZipStream(stream, CompressionMode.Compress, leaveOpen: true);
}
else if (encodingType == "deflate")
{
compressedStream = new DeflateStream(stream, CompressionMode.Compress, leaveOpen: true);
}
return originalContent.CopyToAsync(compressedStream).ContinueWith(tsk =>
{
if (compressedStream != null)
{
compressedStream.Dispose();
}
});
}
}
现在剩下的就是在Application_Start
中注册处理程序了
GlobalConfiguration.Configuration.MessageHandlers.Add(new CompressHandler());
发布于 2012-05-04 16:40:35
如果您使用的是IIS,我会说把压缩留给IIS,因为它支持7+压缩。只有turn it on。
另一方面,对于控制器来说,压缩太接近金属了。理想情况下,控制器应该工作在比字节和流更高的级别。
https://stackoverflow.com/questions/10443588
复制相似问题