Babak
Babak

Reputation: 308

WCF MessageBodyMember with Complex Type and namespace

I Have to implement a WCF service for a given client, so the namespaces and the Contract is not defined by me. The problem is, when I use a complex type as a MessageBodyMember, on the server side the given member is set to null in my server side.

Here is the sample Request:

<?xml version="1.0" encoding="utf-8" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <ns1:CustomeHeader xmlns:ns1="HEADER_NAMESPACE">
            <version>1.0</version>
        </ns1:CustomeHeader>
    </soapenv:Header>
    <soapenv:Body>
        <ns2:in4 xmlns:ns2="NAMESPACE_1">
            <ns39:userID xmlns:ns39="NAMESPACE_2">
                <ns40:ID xmlns:ns40="NAMESPACE_3">someFakeID_123</ns40:ID>
                <ns41:type xmlns:ns41="NAMESPACE_3">0</ns41:type>
            </ns39:userID>
        </ns2:in4>
    </soapenv:Body>
</soapenv:Envelope>

As you can see, the userID is a complex type that its members have defined namespace. It is the MessageBodyMember that I'm talking about.

Here is my interface definition of service and the implementation:

[XmlSerializerFormat]
public interface IIntegrationService
{
    [OperationContract]
    [XmlSerializerFormat]
    SyncOrderRelationshipRsp syncOrderRelationship(SyncOrderRelationshipReq syncOrderRelationshipReq);
}

[ServiceContract]
public class IntegrationService : IIntegrationService
{
    public SyncOrderRelationshipRsp syncOrderRelationship(SyncOrderRelationshipReq syncOrderRelationshipReq)
    {
        //some code here ...
    }
}

And here is the definition of SyncOrderRelationshipReq and UserID:

[MessageContract(IsWrapped = true, WrapperName = "in4", WrapperNamespace = "HEADER_NAMESPACE")]
public class SyncOrderRelationshipReq
{
    [MessageHeader(Namespace = "HEADER_NAMESPACE")]
    public IBSoapHeader IBSoapHeader { get; set; }

    [MessageBodyMember(Namespace = "NAMESPACE_2")]
    public UserID userID { get; set; }
}

[MessageContract(WrapperNamespace = "NAMESPACE_2", IsWrapped = true)]
public class UserID
{
    [MessageBodyMember(Namespace = "NAMESPACE_3")]
    public string ID { get; set; }

    [MessageBodyMember(Namespace = "NAMESPACE_3", Name = "type")]
    public int Type { get; set; }
}

To make the long story short, I need the inner members of a MessageBodyMember have their own namespaces set so that I can read these members.

Upvotes: 3

Views: 1282

Answers (1)

Babak
Babak

Reputation: 308

I've finally found the answer. For anyone who came here to find the answer, this is the answer. First, you should add XmlSerializerFormat attribute to your service interface (which I did already).

Second, you should use XmlType attribute to your complex type class.

Third, use XmlElement attribute for the complex type properties.

So, the UserId class should be like this:

[XmlType]
public class UserID
{
    [XmlElement(Namespace = "NAMESPACE_3")]
    public string ID { get; set; }

    [XmlElement(Namespace = "NAMESPACE_3", Name = "type")]
    public int Type { get; set; }
}

I hope it helps others.

Upvotes: 3

Related Questions