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