wcf methods soap message format - wcf

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.

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.

Force WCF to accept different SOAP message

I'm not sure the title really gets across what I need to do. I want to force or coerce or whatever a WCF service to accept a slightly different SOAP message. Here is what the service expects:
<sch:modifyCandidateNotification>
<!--Optional:-->
<sch:request vueCandidateID="?" clientCandidateID="?" clientCode="?">
...
but here is what I want to send to the service:
<sch:modifyCandidateNotification vueCandidateID="?" clientCandidateID="?" clientCode="?">
I'm not responsible for sending the SOAP, one of our partners is and they can't alter what they are sending. I don't want the structure at all.
I've tried adding [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)] to the interface, but to no avail. Also, I'm using a basicHttpBinding. I've tried with the wsHttpBinding and did not see any difference.
Thanks.

Easier way to Call a SOAP Service with Many Parameters?

My web services are rusty so I hope I'm just missing something kind of obvious.
I have a WCF service that, in part, relays calls it receives to a third party SOAP service. The service receives an object that matches the body of the SOAP message that needs to be sent.
I've added a service reference based on the SOAP service's WSDL to the project and created and instance of the service proxy class. The service method I want to call has 30+ parameters.
I could call it with MyService.TheMethod(obj.value1, obj.value2, obj.value3...), but it would be nice to just pass the original object on or XML serialize it and pass the XML as a body.
Is there something that would allow an easier approach or do I need to individually pass obj's properties onto the SOAP method?
UPDATE
Clarifying the underlying issue.
My .NET service accepts something "Group"
public class Person { string Name; int Age;}
public class Group { string Name; Person[] Individuals; }
I then need to call the third party web service (TPWS). The proxy class generated from the WSDL winds up like:
public class WSPerson { string Name; uint Age;}
public class WSGroup { string Name; WSPerson[] Individuals; }
I'd been doing earlier prototyping and working with the TPWS through SoapUI and using tags matching my original (.NET) classes' naming:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.myabc123.com" xmlns:ns="http://schemas.datacontract.org/2004/07/" xmlns:sys="http://schemas.datacontract.org/2004/07/System" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<soapenv:Header>
<ws:ServiceCredentials>
<ws:SubscriberId>ABC</ws:SubscriberId>
<ws:SubscriberUser>Joe</ws:SubscriberUser>
<ws:SubscriberPassword>12345</ws:SubscriberPassword>
<!--Optional:-->
<ws:SubscriberIdentityStore></ws:SubscriberIdentityStore>
</ws:ServiceCredentials>
</soapenv:Header>
<soapenv:Body>
<Group>
<Name>Cool People</Name>
<Individuals>
<Person>
<Name>Tom</Name>
<Age>25</Age>
</Person>
<Person>
<Name>Jane</Name>
<Age>27</Age>
</Person>
</Individuals>
</Group>
</soapenv:Body>
</soapenv:Envelope>
There's no easy way to do what you want. If the service you're calling has 30 parameters, you'll just have to call it with 30 parameters.
Perhaps this will help others. I'm pursuing the idea of calling the web service through HTTP POST.
The reason is that this general problem will be repeated in similar ways over and over. I control the incoming data contract and the format of the XML that the 3rd party mapping tool ultimately expects. But it generates its own contract for the service. If it can recognize the raw XML that I can produce through XmlSerializer I won't have to map my class just to get the 3rd party tool to in turn perform its own mapping functions.

How to remove xmlns:xsd, xmlns:xsi, xsi:type from the WCF output using XMLSerializer

Using WCF Restful service with XmlSerializer I get the below response.
<?xml version="1.0" encoding="utf-8"?>
<availabilityResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xyz.com/ABCService">
<availabilityResult>
<title xsi:type="Availability_1">
<titleId>0010327457</titleId>
<availability>
<purchasable>false</purchasable>
<availableCopies>0</availableCopies>
<totalCopies>0</totalCopies>
</availability>
</title>
</availabilityResult>
</availabilityResponse>
(I wish to remove xmlns:xsd, xmlns:xsi and xsi:type tags)
"Availability_1" is one my derived type i used in my code. I really do not want to show this in the response.
I am using XmlSerialzer by specifying [XmlSerializerFormat] at the service contract.
WCF is able to serialize my response properly but the only issue i have is with the extra xmlns tags. Yes, I know they are useful stuff there. But, the client is interested only in the plain xml.
By looking at various posts in stackoverflow i understood i could do this by overriding few of the methods of XmlTextWriter. But the problem I have is how to let the WCF know to use my customXmlWriter (inherited from XmlTextWriter) instead of generic XmlTextWriter while serialization.
How to pass my customXmlTextWriter to the XmlSerializer which i do not have any control at this point.
I just created my data classes and defined the service contract methods from my end but did not have to do any of the serialization stuff from my side as the WCF takes care of it on its own.
A slightly different idea, but it's in the line of separation of concerns, as writing custom serialisers to actually make the responses sort of "invalid" seen from a true compliancy principe can be seen as an anti-pattern.
My idea is to develop your own IIS custom HTTP handlers and add it to the IIS processing pipeline. Doing so, will allow you to expose both the tweaked responses and the fully compliant ones.
The custom HTTP handler could use a simple XSLT to remove the required namespaces.
Have a look at this article to get started - http://www.iis.net/learn/develop/runtime-extensibility/developing-iis-modules-and-handlers-with-the-net-framework

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").