Handling Compression (Accept-Encoding) Sample

原文:http://blogs.msdn.com/b/kiranchalla/archive/2012/09/04/handling-compression-accept-encoding-sample.aspx

ps:此人博客非常不错,可以收藏下http://blogs.msdn.com/b/kiranchalla/

Long time back there was a question on forums regarding how we could achieve compression scenario via Accept-Encoding headers in Web API. Thought of bringing that sample here so that it could be useful for anyone looking for this kind of functionality.

NOTE: ASP.NET Web API doesn’t have inherent support for Accept-Encoding header.

Let’s assume we have the following controller which is returning 3 different HttpContents: StringContent, StreamContent & ObjectContent.

public class AcceptEncodingTestsController : ApiController
    {
        [HttpGet]
        public HttpResponseMessage GetStringContent()
        {
            HttpResponseMessage response = new HttpResponseMessage();
            response.Content = new StringContent("Hello World!");

            return response;
        }

        [HttpGet]
        public HttpResponseMessage GetStreamContent()
        {
            HttpResponseMessage response = new HttpResponseMessage();
            response.Content = new StreamContent(new FileStream(@"D\Sample.txt", FileMode.Open));
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
            return response;
        }

        [HttpGet]
        public Customer GetCustomer() // the return value is actually converted to ObjectContent
        {
            return new Customer() { Id = 100, DateOfBirth = new DateTime(1975, 4, 3) };
        }
    }
Encoding handler :
public class EncodingDelegateHandler : 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 &&
                    response.RequestMessage.Headers.AcceptEncoding.Count > 0)
                {
                    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.TryAddWithoutValidation(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();
                }
            });
        }
    }
Register the handler:
config.MessageHandlers.Add(new EncodingDelegateHandler());
With the above example you should see that all the 3 types of contents are compressed via the encoding handler.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值