2011-09-21 151 views
4

我正在嘗試調用WCF服務。用XML調用WCF服務

但是,我有請求正文作爲XML文檔。

因此,例如,而不是此

ListProductsRequest request = new ListProductsRequest(); 
request.Query = new RootQuery(); 
request.Query.Product = "milk"; 
request.Query.Group = "dairy"; 

ListProductsPortType client = new ListProductsPortTypeClient(); 
ListProductsResponse response = client.ListProducts(request); 

我想這樣做:

String xml = "<Root xmlns=\"urn:ns\"><Query><Group>dairy</Group><Product>milk</Product></Query></Root>"; 
var request = // read in to XmlReader or XmlDocument or whatever 
ListProductsPortType client = new ListProductsPortTypeClient(); 
var response = client.ListProducts(request); 

是否有使用生成的代理的方式,與具有數據層安全性的優勢,運輸爲我處理,但不使用代理對象?

感謝, 布萊希特

+0

這是一個REST服務?如果是這樣,那麼你可以直接使用WebClient。 – alf

+0

不,這是一個基於NetTCP的SPNego等SOAP服務。手動操作太複雜了。 我做了類似的事情,我想使用Axis2服務客戶端,但不幸的是Axis2不支持SPNego,所以我試圖在.NET中創建一些通用的調用WCF服務以避免互操作性問題。 編輯:更多解釋+打字 –

+0

我正在尋找一種方法來解決您的問題,並發現這: http://social.msdn.microsoft.com/forums/en-US/wcf/thread/ad917cdd-60d4- 404c-a529-10597ff1bbf8/ 這可能是一個解決方案...使用該消息並將其傳遞到一個通道讓你 選擇如何格式化消息。 這裏有一個Message.Create的例子 http://www.c-sharpcorner.com/UploadFile/dhananjaycoder/7893/ – 2GDev

回答

1

我不認爲你可以調用WCF服務,並通過你想要什麼。

方法ListProducts只接受一個ListProductsRequest對象。所以你必須創建這種對象。

String xml = "<Root xmlns=\"urn:ns\"><Query><Group>dairy</Group><Product>milk</Product></Query></Root>"; 
ListProductsRequest request = MappingObject(xml); 
ListProductsPortType client = new ListProductsPortTypeClient(); 
var response = client.ListProducts(request); 

而在Mapping方法中,您可以使用XML來創建ListproductRequest。

我不知道是否有另一種方式來做到這一點。

+0

它不是真的'我想要的',xml進入對應100%的消息合約在wsdl中。 –

+0

@布雷希特對不起,你是對的... – 2GDev

+0

不需要道歉:) –

0

我想你可以使用

ListProductsRequest request = (ListProductsRequest) new XmlSerializer(
    typeof(ListProductsRequest)).Deserialize(); 

創建相應的對象...

+0

謝謝。這個問題是我從其他地方獲取XML,我希望這是通用的。反序列化方法告訴我XML文檔存在問題('Root'不是預期的),雖然我可以通過簡單的XML讀取它。 我懷疑這是因爲ListProductsRequest有一個指定Wrapper元素名稱的屬性,並且這不是XmlSerializer所期望的。 [System.ServiceModel.MessageContractAttribute(WrapperName =「Root」,WrapperNamespace =「urn:ns」,IsWrapped = true)] –

+0

使用此博客帖子,我能夠反序列化請求。 http://wcfpro.wordpress.com/2010/11/24/customxmlobjectserializer/ –

1

我能走到今天,得益於2GDev的評論。代碼沒有正確處理異常或異常情況。

這樣我可以使用生成的存根的端點(從而重用配置等)

public void CallWs() 
    { 
     WsdlRDListProductsPortTypeClient client = new WsdlRDListProductsPortTypeClient(); 

     String req = "<Root xmlns=\"urn:ns\"><Query><Group>TV</Group><Product>TV</Product></Query></Root>"; 

     CallWs(client.Endpoint, "ListProducts", GetRequestXml(req)); 
    } 

    public XmlElement CallWs(ServiceEndpoint endpoint, String operation, XmlElement request) 
    { 
     String soapAction = GetSoapAction(endpoint, operation); 

     IChannelFactory<IRequestChannel> factory = null; 

     try 
     { 
      factory = endpoint.Binding.BuildChannelFactory<IRequestChannel>(); 
      factory.Open(); 
      IRequestChannel channel = null; 

      try 
      { 
       channel = factory.CreateChannel(endpoint.Address); 
       channel.Open(); 

       Message requestMsg = Message.CreateMessage(endpoint.Binding.MessageVersion, soapAction, request); 
       Message response = channel.Request(requestMsg); 
       return response.GetBody<XmlElement>(); 
      } 
      finally 
      { 
       if (channel != null) 
        channel.Close(); 
      } 
     } 
     finally 
     { 
      if (factory != null) 
       factory.Close(); 
     } 
    } 

    private String GetSoapAction(ServiceEndpoint endpoint, String operation) 
    { 

     foreach (OperationDescription opD in endpoint.Contract.Operations) 
     { 
      if (opD.Name == operation) 
      { 
       foreach (MessageDescription msgD in opD.Messages) 
        if (msgD.Direction == MessageDirection.Input) 
        { 
         return msgD.Action; 
        } 
      } 

     } 

     return null; 
    } 

當我嘗試這個來自MSDN http://msdn.microsoft.com/en-us/library/ms734712.aspx

基本ICalculator樣品,其固定用SPNego,我必須改變這一點,因爲那樣我們需要一個IRequestSessionChannel而不是一個IRequestChannel。

public XmlElement CallWs(ServiceEndpoint endpoint, String operation, XmlElement request) 
    { 
     String soapAction = GetSoapAction(endpoint, operation); 

     IChannelFactory<IRequestSessionChannel> factory = null; 

     try 
     { 


      factory = endpoint.Binding.BuildChannelFactory<IRequestSessionChannel>(); 
      factory.Open(); 
      IRequestSessionChannel channel = null; 

      try 
      { 
       channel = factory.CreateChannel(endpoint.Address); 
       channel.Open(); 

       Message requestMsg = Message.CreateMessage(endpoint.Binding.MessageVersion, soapAction, request); 

       Message response = channel.Request(requestMsg); 
       return response.GetBody<XmlElement>(); 
      } 
      finally 
      { 
       if (channel != null) 
        channel.Close(); 
      } 
     } 
     finally 
     { 
      if (factory != null) 
       factory.Close(); 
     } 
    } 

它所做的談判,和消息似乎被髮送,但不幸的是我現在得到了以下錯誤消息:

No signature message parts were specified for messages with the 'http://Microsoft.ServiceModel.Samples/ICalculator/Add' action. 
+0

最後,我剛剛使用http://wcfpro.wordpress.com/2010/11/24/將xml反序列化爲代理對象customxmlobjectserializer /並使用這些。 –