Ответ 1
Если у вас есть доступ к конфигурации IIS
Вы не можете просто применить заголовок и надеяться, что он будет gzipped - ответ не будет заархивирован.
Вам нужно удалить добавленный заголовок и убедиться, что на вашем сервере IIS включено динамическое сжатие и сжатие статического содержимого.
Один из комментаторов упомянул ссылку на хороший ресурс здесь, в stakoverflow, который показывает, как это сделать:
Обратите внимание, что это будет работать только при настройке значения в файле web.config, если динамическое сжатие уже установлено (которое не находится в установке IIS по умолчанию)
Информацию об этом вы можете найти в документации MSDN: http://www.iis.net/configreference/system.webserver/httpcompression
Простая компрессия
Ниже приведен простой пример выполнения собственного сжатия. В этом примере используется проект Web Api MVC 4 из шаблонов проектов визуальной студии. Чтобы заставить сжатие работать для HttpResponseMessages, вы должны реализовать пользовательский MessageHandler. Ниже приведен рабочий пример.
См. реализацию кода ниже.
Обратите внимание, что я попытался сохранить метод так же, как ваш пример.
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace MvcApplication1.Controllers
{
public class ValuesController : ApiController
{
public class Person
{
public string name { get; set; }
}
// GET api/values
public IEnumerable<string> Get()
{
HttpContext.Current.Response.Cache.VaryByHeaders["accept-encoding"] = true;
return new [] { "value1", "value2" };
}
// GET api/values/5
public HttpResponseMessage Get(int id)
{
HttpContext.Current.Response.Cache.VaryByHeaders["accept-encoding"] = true;
var TheHTTPResponse = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
TheHTTPResponse.Content = new StringContent("{\"asdasdasdsadsad\": 123123123 }", Encoding.UTF8, "text/json");
return TheHTTPResponse;
}
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();
}
});
}
}
}
}
Также добавьте новый обработчик сообщений в конфигурацию вашего приложения.
using System.Web.Http;
using MvcApplication1.Controllers;
namespace MvcApplication1
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.MessageHandlers.Add(new ValuesController.EncodingDelegateHandler());
config.EnableSystemDiagnosticsTracing();
}
}
}
Пользовательский обработчик был составлен - Kiran Challa (http://blogs.msdn.com/b/kiranchalla/archive/2012/09/04/handling-compression-accept-encoding-sample.aspx)
Есть лучшие примеры, которые реализуют дефлирование входящих потоков, также вы можете увидеть примеры ниже:
- http://www.codeproject.com/Articles/557232/Implementing-a-Custom-DelegatingHandler-in-ASP-NET
- http://ronaldrosiernet.azurewebsites.net/blog/2013/07/16/implement_compression_in_aspnet_web_api
Кроме того, я нашел действительно хороший проект, который поддерживает все это в github.
Обратите внимание, что я пришел к этому ответу сам Саймон в ваших комментариях предложил этот подход 2 дня назад с даты этого ответа.