I’m trying to create a WSTransfer implementation (I realise Roman Kiss has written one already for WCF – but it doesn’t actually meet the specifications)
I’ve ended up abandoning data contracts on the service contacts because WSTransfer is loosely coupled; so each the create message looks like Message Create(Message request).
This works fine, and everything is lovely until it’s time to fire back a response.
The problem I have is in the way a WSTransfer response is constructed. Taking create as the example the response looks like
<wxf:ResourceCreated> <wsa:Address>....</wsa:Address> <wsa:ReferenceProperties> <xxx:MyID>....</xxx:MyId> </wsa:ReferenceProperties> </wxf:ResourceCreated>
As you can see there are 3 different XML namespaces within the response message.
Now, it’s easy enough when one is involved; you can (even if you’re not exposing it), create a data contract and set the values and fire it back
Message response = Message.CreateMessage(request.Version, 'http://schemas.xmlsoap.org/ws/2004/09/transfer/CreateResponse', resourceCreatedMessage);
However the problem arises in setting different namespaces for the child elements within the response; it appears WCF’s datacontracts don’t do this. Even using
[MessageBodyMember(Namespace='....')]
on the individual elements within the response class don’t appear to make any changes, everything becomes part of the namespace specified for the contract class.
So how do I apply different namespaces to individual elements in a WCF Message; either via a contract, or via some other jiggery pokery?
So following up jezell’s answer; the problem with using XmlSerialization when creating a message by hand is that the child elements of the root get their element names mangled. This happens because despite the operation contract being marked as [XmlSerializerFormat] when you create a message by hand the DataContractSerializer is used.
You cannot pass the XmlSerializer into Message.CreateMessage() because it demands an XmlObjectSerializer, which XmlSerializer is not.
So the answer appears to be write a wrapper class for XmlSerializer, which has XmlObjectSerializer as its base class (here’s an example) and pass that in; along with your message holding class.
Unfortunately it’s not clever enough to setup prefixes in the XML; so you end up with messages like
But it’s all equivalent.