2011-07-03 104 views
0

我正在嘗試動態調用WCF服務。我可以連接到服務並調用不需要任何參數的方法。運行時動態調用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); 
    } 

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

從上述的CreateMessage代碼生成以下的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> 

然而,爲了爲Person實體將被彈出ulated和正確的經營合同要執行的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

我不知道你爲什麼做這個硬盤的方式,但如果你想打電話給你顯示你必須先提供消息的合同到客戶端的方法期待SOAP請求:

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

而且您還需要類似的響應合同。

默認序列化使用從操作合同名稱推斷的包裝器,但由於您沒有提供服務合約,因此您的序列化程序不知道現有的包裝程序,因爲您必須手動提供這些附加知識或重新定義您的服務, t期望包裝元素(它也用消息合同完成並將它們的IsWrapped屬性設置爲false)。

+0

謝謝拉迪斯拉夫,這很有道理...... – lihnid