WCF service custom response - wcf

I have developed a demo WCF service with basicHttpBinding and I'm getting WCF response as fellow -
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<TestResponse xmlns="http://tempuri.org/">
<TestResult>hi Test</TestResult>
</TestResponse>
</s:Body>
</s:Envelope>
But I need WCF response in following format-
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
-->><t:TestResponse xmlns:t="http://tempuri.org/">
<TestResult>hi Test</TestResult>
</TestResponse>
</s:Body>
</s:Envelope>
so what can I do to get this reponse??

Notice that the two responses you have aren't equivalent: in the first one the <TestResult> element is in the tempuri.org/ namespace, while in the second one it's on the default ("") one (you'd need to prefix TestResult with "t:" as well to maintain the same XML semantics. To accomplish this, there's nothing in WCF which will do it out of the box, but you can change it yourself using one of the many extensibility points of the platform. Take a look at http://blogs.msdn.com/b/carlosfigueira/archive/2010/06/13/changing-prefixes-in-xml-responses.aspx which deals exactly with that.

Related

How can I change xmlns of root tag Envelop in soap request in WCF

I need to change xmlns of root tag Envelope in soap request in WCF. Like now WCF creating following request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"></s:Envelope>
But I need to create like following
<soapenv:Envelope xmlns:abc="abc.astute.ca/"; xmlns:xyz="xyz.astute.ca/"; xmlns:asd="asd.astute.ca/"; xmlns:qwe="qwe.astute.ca/"; xmlns:soapenv="schemas.xmlsoap.org/soap/envelope/">
Any idea?
I would advise not to do it (there is almost never a reason to do it). If this is a requirement than you could do it in a custom message encoder - you would need to change all places where the prefix is referred to as well.

wcf methods soap message format

I know the defined soap message format.
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://localhost:5000/axis2/services/xdsrepositoryb</wsa:To>
<wsa:MessageID>urn:uuid:AFBE87CB65FD88AC4B1220879854302</wsa:MessageID>
<wsa:Action>urn:ihe:iti:2007:ProvideAndRegisterDocumentSet-b</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<xdsb:ProvideAndRegisterDocumentSetRequest xmlns:xdsb="urn:ihe:iti:xds-b:2007">
<lcm:SubmitObjectsRequest xmlns:lcm="urn:oasis:names:tc:ebxml-regrep:xsd:lcm:3.0">
<rim:RegistryObjectList xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0">
<rim:ExtrinsicObject id="Document01" mimeType="text/plain"/>
</rim:RegistryObjectList>
</lcm:SubmitObjectsRequest>
<xdsb:Document id="Document01">base64 content goes here</xdsb:Document>
</xdsb:ProvideAndRegisterDocumentSetRequest>
</soapenv:Body>
I want to write a wcf service to exposed a method that can consume that kind of soap meassage.
I just don't know the relationship between the soap message and wcf method. Be more specific, what's the relationship between wcf methods, parameters and soap meassage ?
How can I write a wcf method that conform to the soap meassage above ?
While you can probably build a data contract that matches this particular example by working your way backwards, it is not generally a good idea. The sample might not be representative of the data that can be passed. Instead, you will be much better off by obtaining an official WSDL document or a set of XSDs that describe the contract.
If you're curious how a particular WCF message looks like in raw SOAP form, the easiest way to see that is probably to enable WCF tracing and look at the trace.

Set namespaces in SOAP envelope for classes generated using svcutil

We are working on a third party integration using WSDLs and XSDs that were provided to us. We've used svcutil to generate all the proxy classes for us which works fine. When we test with SoapUi everything works fine, however, when we try to send the response to our partner they're rejecting the SOAP message because the namespaces are being defined in the message header and body rather than the SOAP envelope.
Unfortunately, I can't make our partner change their process to accept our messages (even though I believe they are technically correct since we are defining the namespaces before we use them in the XML, just not where they expect them). I know I could put a message inspector in to massage the SOAP message before goes out, but I'd rather not go to that level of processing.
Are there any settings either for svcutil or even on the serialization attributes that we could set to have WCF output the namespaces on the envelope instead?
What they want:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:h="http://theirdomain.org/service">
<s:Header>
<h:myType>
<version>V1.0</version>
</h:myType>
</s:Header>
<s:Body>
<h:someElement />
</s:Body>
</s:Envelope>
What we're sending:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" >
<s:Header>
<h:myType xmlns:h="http://theirdomain.org/service">
<version>V1.0</version>
</h:myType>
</s:Header>
<s:Body>
<h:someElement xmlns:h="http://theirdomain.org/service"/>
</s:Body>
</s:Envelope>
I think the right extensibility point for this may be a custom encoder (see http://msdn.microsoft.com/en-us/library/ms735115.aspx , or the samples at http://msdn.microsoft.com/en-us/library/ee960159.aspx , especially the first one). In the custom encoder, you would write the SOAP Envelope yourself (with the correct namespaces), and then call methods on the Message object to write out the headers and body (e.g. WriteBodyContents, see http://msdn.microsoft.com/en-us/library/ms734675.aspx - under "Writing Messages").

VB.net SOAP webservice client "Unmarshalling Error: unexpected element ..."

I am building a client in VB.net for calling webservices methods from a partner organisation.
I am following the guidelines at http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soaphttpclientprotocol%28v=VS.71%29.aspx because I can't get it to work using the Web References feature of Visual Studio 2010 (when I try to do that it turns the methods from the WSDL into classes).
I have created a proxy class and can instantiate an object of that class no problem.
However, when I try to call a method which requires arguments I get this error:
Unmarshalling Error: unexpected element (uri:"http://api.service.apimember.emailvision.com/", local:"key"). Expected elements are <{}key>,<{}login>,<{}pwd>
Does anyone have any idea why this might be? (If it's helpful I can post my code and the location of the WSDL.)
(P.S. I can get the whole thing to work fine in PHP using ZF Soap classes, but for various reasons I need to get it to work using .Net)
Edit to add: I have used Wireshark to examine the outgoing and incoming SOAP message to compare them with the messages being sent via SoapUI, where it all works fine.
What this has shown is that my VB client is sending a message where the namespace of the web service I am trying to access is declared as an attribute of the method, and not in the soap:envelope attributes.
Here is an example:
WORKS (produced by SoapUI):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:api="http://api.service.apimember.emailvision.com/">
<soapenv:Header/>
<soapenv:Body>
<api:openApiConnection>
DOESN'T WORK (produced by my VB.net code):
<?xml version="1.0" encoding="utf-8"?>
<soap:envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:body>
<openApiConnection xmlns="http://api.service.apimember.emailvision.com/">
I think I need to declare the xmlns 'api' in the envelope element, so I need to figure out how to do this in my VB.net code.
OK, turns out I was using System.Web.Services.Protocols.SoapDocumentMethodAttribute but I should have been using System.Web.Services.Protocols.SoapRpcMethodAttribute.
Using the RPC binding style produces the message body format the remote service requires. Having read up a bit about how the attributes in the MS code I was basing my code on were affecting my output I came across this page http://msdn.microsoft.com/en-us/library/k1y9z356(v=vs.80).aspx which led me to changing the binding method, and that works.

Change namespace Prefix WCF Envelope

I was wondering is there anyway to change the namespace prefix for the WCF SOAP request?
As you can see in the example below, The Envelope has namespace "http://www.w3.org/2005/08/addressing" with prefix 'a'. I want to change this to 'foo'. How can I do that.
Note I dont have control over service code I can only create proxy class from the WSDL .
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.starstandards.org/webservices/2005/10/transport/operations/MyAction</a:Action>
<h:payloadManifest xmlns="http://www.starstandards.org/webservices/2005/10/transport" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="http://www.starstandards.org/webservices/2005/10/transport">
<manifest contentID="Content0" namespaceURI="http://www.starstandard.org/STAR/5" element="TESTMETHOD" version="5.2.4"></manifest>
</h:payloadManifest>
<h:Identity xmlns="urn:xxx/xxx/" xmlns:h="urn:xxx/xxx">
<SiteCode>XXXXXX</SiteCode>
</h:Identity>
<a:To>urn:xxx/xxx/Method1</a:To>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">XXXXX</MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
</s:Header>
This can be done on Client or Server side by using a MessageFormatter. You can also change this with a MessageEncoder, but this has many problems.
This article describes how to do this on server side using a MessageFormatter and also the downside of a MessageEncoder:
http://vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix
What you need to do is to apply the MessageFormatter client side (maybe using ApplyClientBehavior instead of ApplyDispatchBehavior). Also, in the custom message class you need to add your namespace as attribute, with the "foo" prefix (in the OnWriteStartEnvelope method).
Unfortunately, there is no easy way (like applying some attributes) that will make the change you need.
WCF provides ability to control most of the SOAP Envelop details using message contracts. But I doubt if you can do something with the namespace prefix. You can control the namespace however.
Please refer to Using Message Contracts
I'm not aware of any way to control the prefixes WCF uses in its standard message encoders.
I think you would have to write a custom message encoder if you want the message on the wire to use different prefixes.