WCF GZip Сжатие Запрос / Обработка Ответа

Как получить клиент WCF для обработки ответов сервера, которые были разархивированы или разорваны IIS?

В IIS я следовал приведенным здесь инструкциям о том, как сделать IIS 6 gzip для всех ответов (где запрос содержал "Accept-Encoding: gzip, deflate"), отправляемых службами.svc wcf.

На клиенте я следовал инструкциям здесь и здесь о том, как вставить этот заголовок в веб-запрос: "Accept-Encoding: gzip, deflate".

Fiddler2 показывает, что ответ является двоичным, а не простым старым Xml.

Клиент аварийно завершает работу с исключением, которое в основном говорит, что нет XML-заголовка, что, конечно, верно.

В моем IClientMessageInspector происходит сбой приложения до вызова AfterReceiveReply.

Некоторые дальнейшие заметки:

(1) Я не могу изменить службу или клиент WCF, так как они предоставлены третьей стороной. Однако я могу прикрепить поведение и / или инспекторов сообщений через конфигурацию, если это правильное направление.

(2) Я не хочу сжимать / распаковывать только мыльное тело, но все сообщение.

Есть идеи / решения?

* Решено *

Не было возможности написать расширение WCF для достижения этих целей. Вместо этого я следовал за этой статьей CodeProject, которая защищает вспомогательный класс:

public class CompressibleHttpRequestCreator : IWebRequestCreate
{
    public CompressibleHttpRequestCreator()
    {
    }

    WebRequest IWebRequestCreate.Create(Uri uri)
    {
        HttpWebRequest httpWebRequest = 
            Activator.CreateInstance(typeof(HttpWebRequest),
            BindingFlags.CreateInstance | BindingFlags.Public | 
            BindingFlags.NonPublic | BindingFlags.Instance,
            null, new object[] { uri, null }, null) as HttpWebRequest;

        if (httpWebRequest == null)
        {
            return null;
        }

        httpWebRequest.AutomaticDecompression =DecompressionMethods.GZip | 
            DecompressionMethods.Deflate;

        return httpWebRequest;
    }
} 

а также дополнение к файлу конфигурации приложения:

<configuration>
  <system.net>
    <webRequestModules>
      <remove prefix="http:"/>
      <add prefix="http:" 
            type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
    </webRequestModules>
  </system.net>
</configuration>

Кажется, что происходит то, что в конечном итоге WCF запрашивает какую-то фабрику или другой источник в system.net, чтобы предоставить экземпляр HttpWebRequest, и мы предоставляем помощника, которому будет предложено создать требуемый экземпляр.

В файле конфигурации клиента WCF все, что требуется, это простой basicHttpBinding без каких-либо пользовательских расширений.

Когда приложение запускается, клиентский Http-запрос содержит заголовок "Accept-Encoding: gzip, deflate", сервер возвращает сжатый веб-ответ, и клиент прозрачно распаковывает http-ответ перед его передачей в WCF.

Когда я попытался применить эту технику к веб-сервисам, я обнаружил, что она НЕ работает. Хотя вспомогательный класс выполнялся так же, как и при использовании клиентом WCF, запрос http не содержал заголовок "Accept-Encoding: ...".

Чтобы это работало для веб-служб, мне пришлось отредактировать класс веб-прокси и добавить этот метод:

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
    System.Net.HttpWebRequest rq = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
    rq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    return rq;
}

Обратите внимание, что не имело значения, присутствовали CompressibleHttpRequestCreator и блок из файла конфигурации приложения или нет. Для веб-сервисов работало только переопределение GetWebRequest в Прокси-сервер веб-службы.

2 ответа

Спасибо за ваш совет WCF! Мы собираемся включить сжатие IIS для служб в моем магазине, и я надеюсь, что ваше решение будет работать. Под "Чтобы это работало для веб-сервисов" - вы имели в виду клиентов SoapHttpProtocol старой школы? Потому что класс SoapHttpProtocol имеет встроенное свойство EnableDecompression, которое будет автоматически обрабатывать заголовок Compression и обработку ответов.

Вот ответ, который я дал на другой вопрос по этому вопросу. Этот вопрос был задан с точки зрения ADO.NET Data Services, но мой ответ был чисто о WCF.

Другие вопросы по тегам