Динамически вызывать службу WCF во время выполнения - PullRequest
0 голосов
/ 03 июля 2011

Я пытаюсь вызвать службу WCF динамически. Я могу подключиться к службе и вызывать методы, которые не требуют никаких параметров.

ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(this.ServiceBinding, this.EndPoint.Address);

IRequestChannel channel = factory.CreateChannel();

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

Следующий код используется для создания экземпляра сообщения запроса:

Message requestMessage = Message.CreateMessage(this.ServiceBinding.MessageVersion, contractNameSpace, new SimpleMessageBody(value));

Значение, используемое в классе SimpleMessageBody, является сериализованным значением сущности, использующей DataContractSerializer.

<Person xmlns="http://schemas.datacontract.org/2004/07/WcfService.Test.Service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Name>John Smith</Name></Person>

Операционный договор

public string GetData(Person value)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            value = new Person { Name = "John Smith" };
            DataContractSerializer ser = new DataContractSerializer(typeof(Person));
            ser.WriteObject(ms, value);

            var result = UnicodeEncoding.UTF8.GetString(ms.ToArray());
        }

        return string.Format("You entered: {0}", value.Name);
    }

Entity

[DataContract]
public class Person
{
    [DataMember]
    public string Name { get; set; }
}

Следующее сообщение SOAP генерируется из приведенного выше кода создания сообщения:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/IService1/GetData</a:Action>
    <a:MessageID>urn:uuid:cf78d5b7-333b-40eb-a71c-d81cb9c37b5d</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <a:To s:mustUnderstand="1">http://localhost:52724/Service1.svc</a:To>
  </s:Header>
  <s:Body><Person xmlns="http://schemas.datacontract.org/2004/07/WcfService.Test.Service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Name>John Smith</Name></Person></s:Body>
</s:Envelope>

Однако для заполнения сущности «Лицо» и выполнения правильного контракта на выполнение операций SOAP должен быть следующим:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/IService1/GetData</a:Action>
    <a:MessageID>urn:uuid:d49bd525-0f30-46fe-94fb-0248c2cb1ea2</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
  </s:Header>
  <s:Body>
    <GetData xmlns="http://tempuri.org/">
      <value xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfService.Test.Service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <d4p1:Name>John Smith</d4p1:Name>
      </value>
    </GetData>
  </s:Body>
</s:Envelope> 

Пожалуйста, ПРИМЕЧАНИЕ Тело сообщения.

Спасибо

1 Ответ

1 голос
/ 03 июля 2011

Я не знаю, почему вы делаете это таким сложным способом, но если вы хотите вызвать метод, ожидающий SOAP-запрос, который вы показали, вы должны сначала предоставить контракт сообщения вашему клиенту:

[MessageContract(WrapperName="GetName")]
public class MessageContract
{
    [MessageBodyMember(Name="value")]
    public Person Person { get; set; }
}

И выдля ответа также потребуется аналогичный контракт.

В сериализации по умолчанию используются оболочки, выведенные из имен контракта на обслуживание, но поскольку вы не предоставляете контракт на обслуживание, ваш сериализатор не знает о существующих оболочках, поскольку вам необходимо предоставить эти дополнительные знания.вручную или переопределите ваш сервис так, чтобы он не ожидал элементов-оболочек (это также делается с контрактами сообщений и установкой для их свойств IsWrapped значения false).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...