Creating WCF Messages with Multiple Namespaces

I am trying to create an implementation of WSTransfer (I understand that Roman Kiss wrote one already for WCF - but it doesn't actually meet the specs)

I ended up giving up the data contracts in the service contacts because WSTransfer is loosely coupled; so each create message looks like a Message Create (Message request).

It works great and everything is great until it's time to respond.

The problem I am having is how the WSTransfer response is generated. Taking the answer as an example, it 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 in the response post.

Now, it's easy enough when it is involved; you can (even if you don't expose it) create a data contract and set the values ​​and run it back

Message response = Message.CreateMessage(request.Version, 
            "http://schemas.xmlsoap.org/ws/2004/09/transfer/CreateResponse",
            resourceCreatedMessage);

      

However, a problem arises when setting up different namespaces for the children in the response; it looks like WCF datacontracts don't. Even using

[MessageBodyMember(Namespace="....")]

      

does not make any changes for individual elements in the response class, everything becomes part of the namespace specified for the contract class.

So how do I apply different namespaces to individual elements in a WCF post? either through a contract or through some other poker establishment?

0


source to share


2 answers


So, after jezell's answer; The problem with using XmlSerialization when creating a message manually is that the child elements of the root get mangled names of their elements. This is because even though the work contract is marked as [XmlSerializerFormat], when you manually create the message, the DataContractSerializer is used.

You cannot pass an XmlSerializer to Message.CreateMessage () because it requires an XmlObjectSerializer, which is not an XmlSerializer.

So the answer seems to be writing a wrapper class for the XmlSerializer that has the XmlObjectSerializer as its base class ( example here ) and pass that in; along with your message storage class.

Unfortunately, this is not smart enough to prefix XML; so you get messages like



<ResourceCreated xmlns="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/">http://localhost:8731/Design_Time_Addresses/AddTests/WSTransfer/</Address>
  <ReferenceType xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/"></ReferenceType>

      

But they are all equivalent.

0


source


In such a case, when you need precise control over the XML output, you should use XmlSerializer instead of DataContract or MessageContract for serialization. Here are some more details on how to do it:



http://msdn.microsoft.com/en-us/library/ms733901.aspx

0


source







All Articles