Подтвердить что ты не робот

Обработка запроса/ответа WCF GZip

Как мне получить WCF-клиент для обработки ответов сервера, которые были GZipped или Deflated с помощью IIS?

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

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

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

Клиент выходит из строя с исключением, которое в основном говорит, что нет заголовка Xml, который, к сожалению, верен.

В моем IClientMessageInspector приложение вылетает до вызова функции AfterReceiveReply.

Некоторые дополнительные примечания:

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

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

Любые идеи/решения?

* SOLVED *

Не удалось написать расширение 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 в конце концов просит некоторых factory или других глубоко в system.net предоставить экземпляр HttpWebRequest, и мы предоставляем помощника, которому будет предложено создать требуемый экземпляр.

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

Когда приложение запускается, клиентский запрос Http содержит заголовок "Accept-Encoding: gzip, deflate", сервер возвращает gzipped-ответ в сети, а клиент прозрачно распаковывает ответ 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 в прокси-сервере веб-службы.

4b9b3361

Ответ 1

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

Ответ 2

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