Как получить клиент WCF для обработки ответов сервера, которые были GZipped или дефлированы 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 в Прокси-сервер веб-службы.