Call the WCF service using XML

I am trying to call a WCF service.

However, I have a request body as an XML document.

So for example, instead

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); 

I want to do this:

 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); 

Is there a way to use the generated proxy server in order to ensure the security and level of data transfer for me, but without using proxy objects?

Thanks Brecht

+4
source share
3 answers

I don’t think you can call the WCF service and pass what you want.

The ListProducts method accepts only a ListProductsRequest object. Therefore, you need to create such an object.

 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); 

And in the mapping method, you can work with your XML to create a ListProductRequest.

I do not know if there is another way to do this.

+1
source

I got this far, thanks to 2GDev's comment. Code without proper handling of exceptions or abnormal situations.

That way I can use the created endpoint stub (and thus reuse the configuration, etc.).

  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; } 

When I try this with the base ICalculator sample from msdn http://msdn.microsoft.com/en-us/library/ms734712.aspx

What is protected by SPNego, I have to change this a bit, because then we need an IRequestSessionChannel instead of an 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(); } } 

It negotiates and the message seems to be sent, but unfortunately now I get the following error message:

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

I think you could use

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

to create the corresponding object ...

0
source

All Articles