Как настроить клиент WCF для работы со сторонней службой WS, размещенной на сервере, который не возвращает тип содержимого в ответе? - PullRequest
1 голос
/ 12 ноября 2010

Как настроить клиент WCF для работы со сторонней службой WS, размещенной на сервере, который не возвращает тип содержимого в ответе?

Проблема заключается в том, что такой клиент WCF, настроенный на использование basicHttpBinding, выдает исключение: «требуется тип содержимого» ...

Должен ли я использовать пользовательские привязки или отказаться от WCF?

P.S. .NET 3.5

P.P.S Сообщение: HTTP-заголовок Content-Type необходим для обмена сообщениями SOAP, но ни один не найден Трассировка стека сервера: в System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse (запрос HttpWebRequest, ответ HttpWebResponse, фабрика HttpChannelFactory, WebException responseException)

at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply (TimeSpan timeout) в System.ServiceModel.Channels.RequestChannel.Request (сообщение-сообщение, время ожидания TimeSpan) в System.ServiceModel.Dispatcher.RequestChannelBinder.Request (сообщение-сообщение, время ожидания TimeSpan) в System.ServiceModel.Channels.ServiceChannel.Call (строковое действие, логический односторонний режим, операция ProxyOperationRuntime, Object [] ins, Object [] outs, TimeSpan timeout) в System.ServiceModel.Channels.ServiceChannel.Call (строковое действие, логический односторонний режим, операция ProxyOperationRuntime, Object [] ins, Object [] outs) в System.ServiceModel.Channels.ServiceChannelProxy.InvokeService (метод IMethodCallMessageCall, операция ProxyOperationRuntime) в System.ServiceModel.Channels.ServiceChannelProxy.Invoke (сообщение IMessage)

Исключение переброшено в [0]: в System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage (IMessage reqMsg, IMessage retMsg) в System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & msgData, тип Int32) в блаблабле (нестандартный код)

Ответы [ 2 ]

0 голосов
/ 22 ноября 2010

Мне кажется, я нашел схему, как ее можно взломать.

Наследовать новый класс от System.ServiceModel.Channels.HttpChannelFactory + HttpRequestChannel + HttpChannelRequest и переопределить виртуальный метод WaitForReply

Наследовать новый класс от System.ServiceModel.Channels.HttpChannelFactory + HttpRequestChannel и переопределить метод интерфейса CreateRequest (Message)

Наследовать новую форму класса System.ServiceModel.Channels.HttpChannelFactory и переопределить метод OnCreateChannel (EndpointAddress remoteAddress, Uri via)

проблема: все эти классы являются частными и внутренними (!). решение, создайте их во время выполнения, используя: reflection / emit / TypeBuilder / codedom. Все упомянутые методы являются короткими (только WaitForReply является подробным), и все методы являются виртуальными - там нам действительно повезло.

затем наследуется от Http (s) TransportBindingElement и переопределить BuildChannelFactory (контекст BindingContext);

, а затем создать пользовательскую привязку

:)

P.S. Я не уверен, что возможно создать новый тип, наследующий его от внутреннего защищенного класса, от другой сборки, но я думаю, что это возможно.

0 голосов
/ 16 ноября 2010

Я могу сказать, что это невозможно.Я хочу показать, почему:

Очень глубокий внутренний код (System.ServiceModel.Channels.HttpChannelFactory + HttpRequestChannel + HttpChannelRequest класс, метод WaitForReply) - вам никогда не захочется делать фокусы наследования и рефлексии с этими внутренними классами -содержит две строки

var response = (HttpWebResponse) this.webRequest.GetResponse ();// webRequest является типом HttpWebRequest.

public class FakedHttpWebRequest: HttpWebRequest
{

        protected FakedHttpWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
        {
        }

        public override WebResponse GetResponse()
        {
            WebResponse wr = base.GetResponse();
            wr.ContentType = "text/xml";
            return wr;
        }
}

и затем нам нужно использовать отражение где-нибудь, создать FakedHttpWebRequest вместо HttpWebRequest ...

К сожалению, на этот раз «где-то» кажется статическим (!) Методом (WebRequest.Create),так что нет никаких шансов остаться в области "небольшого взлома".

...