Позвоните в службу WCF, не зная договора - PullRequest
1 голос
/ 15 октября 2011

Я пытаюсь сделать следующее:

У меня есть служба Windows, на которой запущена служба TCP WCF.

Теперь я хочу реализовать клиент, который может подключаться к этому сервису. Но этот клиент не знает договора на обслуживание. Он знает, что служба предоставляет метод Download (string path). Я хочу подключиться к услуге и позвонить Download("c:\\temp\\xxx.exe").

Я пробовал следующее:

var myBinding = new NetTcpBinding(SecurityMode.None)
{
    TransferMode = TransferMode.Streamed,
    MaxBufferPoolSize = 524288,
    MaxBufferSize = 2147483647,
    MaxConnections = 254,
    MaxReceivedMessageSize = 2147483647,
    PortSharingEnabled = true
};

var myEndpoint = new EndpointAddress("net.tcp://localhost:6648/InstallerBootstrapperService");

var myChannelFactory = new ChannelFactory<IInstallerBootstrapperService>(myBinding, myEndpoint);

IInstallerBootstrapperService client = null;

try {
    client = myChannelFactory.CreateChannel();
    client.Download("c:\\temp\\xxx.exe");
    ((ICommunicationObject) client).Close();
} catch {
   if (client != null) {
        ((ICommunicationObject) client).Abort();
   }
}

Но это вызывает исключение, когда я звоню Download(). Это говорит:

Сообщение с действием «Prayon.Service.Library / IInstallerBootstrapperService / Download» не может обрабатываться на приемнике из-за несоответствия ContractFilter на EndpointDispatcher. Это может быть из-за несоответствия контракта (несоответствующие действия между отправителем и получателем) или привязка / безопасность несоответствие между отправителем и получателем. Проверьте отправителя и получатель имеют одинаковый договор и одинаковую привязку требования безопасности, например Сообщение, Транспорт, Нет).

Есть ли способ, которым я могу вызвать метод обслуживания, не зная контракт? Могу ли я что-то изменить на стороне службы, чтобы этот клиент всегда мог вызывать метод?

1 Ответ

2 голосов
/ 17 октября 2011

Сервер не имеет представления о том, что клиент имеет в качестве контракта, а сервер знает, что клиент отправляет его в виде запроса SOAP, который должен содержать правильную информацию внутри, поэтому сантехника WCF найдет соответствующий контракт по типу службы и найдет операцию, которая будет соответствовать также. В зависимости от настроек фильтра тип сервиса вместе с настройками ServiceModel может быть настроен на отказ от использования фильтрации, и в этом случае вам не нужно, например, сопоставлять пространства имен, более того, сервер может быть настроен таким образом, чтобы конкретный метод перехватывал все вызовы из клиенты, независимо от информации, размещенной в запросе SOAP.

Итак, ошибка, которую вы получаете, ясно говорит о том, что несоответствие фильтра означает, что либо свойство пространства имен контракта на клиенте не совпадает с сервером, либо параметры безопасности отличаются

для исправления пространства имен вы определяете контракт на клиенте следующим образом

 [ServiceContract(
      Namespace="namespaceuri",
      Name="contractname")]
 public interface IInstallerBootstrapperService {

      [OperationContract(
             Namespace="namespaceuri", 
             Action ="actionuri", 
             ReplyAction="replyactionuri")]
      void Download( string path);

 }

и свойство namespace обоих атрибутов должно совпадать с таковым на сервере.

для исправления других настроек, которые могут не соответствовать, вам необходимо знать, что за транзакция Flow, безопасность транспорта и сообщений, а также кодировка и версия сообщений конечной точки сервера

сначала попробуйте настройки по умолчанию для netTcp, которые могут совпадать

...