Как мне получить 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 в прокси-сервере веб-службы.