0

I have a WCF service using MessageContracts. The thing that is giving me a headache is that if the order of the elements in the message is changed, then the service will ignore the element. Here is an example (with non-pertinent details removed): If I send

<soapenv:Envelope ...>
   <soapenv:Header/>
   <soapenv:Body>
      <bci:MySampleRequest>
         <bci:Apples>some value here</bci:Apples>
         <bci:Bananas>another value here</bci:Bananas>
         <bci:Oranges>something else</bci:Oranges>
      </bci:MySampleRequest>
   </soapenv:Body>
</soapenv:Envelope>

then that works just fine. But if instead I send

<soapenv:Envelope ...>
   <soapenv:Header/>
   <soapenv:Body>
      <bci:MySampleRequest>
         <bci:Bananas>another value here</bci:Bananas>
         <bci:Apples>some value here</bci:Apples>
         <bci:Oranges>something else</bci:Oranges>
      </bci:MySampleRequest>
   </soapenv:Body>
</soapenv:Envelope>

then the Bananas value is ignored, and comes through as NULL. My MessageContract class looks like this:

[WCF::MessageContract(WrapperName = "MySampleRequest", WrapperNamespace = "...")] 
public partial class MySampleRequest {
    private string bananas;
    private string apples;
    private string oranges;

    [WCF::MessageBodyMember(Namespace = "...", Name = "Bananas")]
    public string Bananas {
        get { return effectiveDate; }
        set { effectiveDate = value; }
    }

    [WCF::MessageBodyMember(Namespace = "...", Name = "Apples")]
    public string Apples {
        get { return apples; }
        set { apples = value; }
    }

    [WCF::MessageBodyMember(Namespace = "...", Name = "Oranges")]
    public string Oranges {
        get { return oranges; }
        set { oranges = value; }
    }
}

I should also mention we are using the DataContractSerializer, and while my examples here are simple strings, the actual message objects are much more complex and include lists and DataContract objects.

It looks like WCF is by default ordering the members alphabetically. I honestly don't even care what ordering is used. What I want is for consumers to be able to pass in those values in any order they want to, and have the service still work. XML is easy to read even when order is not specified, so this seems like it should be doable.

Please note that I'd really rather not change serializers or change from MessageContract to DataContract - this is an existing service in our production environment and I really can't make a change that will cause the WSDL to be incompatible with existing code. When I have played with changing these MessageContracts into DataContracts, it causes the structure of the WSDL to change enough to be incompatible with existing code.

Sean Worle
  • 861
  • 1
  • 7
  • 19

1 Answers1

0

Does the WSDL wrap a <sequence> element around the attributes you want to pass in any order? That's likely your limitation. WCF is just following the rules of the contract.

Removing <sequence> from the WSDL will likely break backward compatibility (although its worth a quick test to try). So I'm not sure you can do what you are asking AND maintain existing code.

ErnieL
  • 5,773
  • 1
  • 23
  • 27
  • Looking at the WSDL, it does look like it's including tags. So I guess you're right about not being able to change this and still maintain existing code. Any idea what about anything that could be done in the C# code to prevent the WSDL from being generated this way? (I'm guessing not, this is probably just something that WCF does.) – Sean Worle Nov 23 '16 at 21:38