1

This question is very similar to this one: Not all parameters in WCF data contract make it through the web service call. However, the answer provided there did not solve my problem.

This is my service-code:

using System.Runtime.Serialization;
using System.ServiceModel;
namespace SoapUiToWcf
{
    [ServiceContract]
    public interface IWcfTest
    {
        [OperationContract]
        WcfData ReturnRequest(WcfData wcfData);
    }

    [DataContract]
    public class WcfData
    {
        [DataMember(Order = 1)]
        public WcfDataNested NestedData { get; set; }

        public class WcfDataNested
        {
            [DataMember(Order = 2)]
            public string Foo { get; set; }
            [DataMember(Order = 3)]
            public string Bar { get; set; }
        }
    }

    public class WcfTest : IWcfTest
    {
        public WcfData ReturnRequest(WcfData wcfData)
        {
            return wcfData;
        }
    }
}

The service should return the identical data which was sent to it. When i send a request through SoapUI with the data below, everything works fine and i get all the values back which have been sent:

<soapenv:Envelope><soapenv:Header/><soapenv:Body><tem:ReturnRequest><tem:wcfData>
    <soap:NestedData>
        <soap:Bar>bar</soap:Bar>
        <soap:Foo>foo</soap:Foo>
    </soap:NestedData>
</tem:wcfData></tem:ReturnRequest></soapenv:Body></soapenv:Envelope>

but if i swap the Bar- and Foo-fields in the request, the wcf-service only receives the foo-value, the other one is null:

<a:Bar i:nil="true"/>
<a:Foo>foo</a:Foo>

EDIT

Screenshot 1 (request and respone in SoapUI): enter image description here

Screenshot 2 (Debugging in Visual Studio): enter image description here

How do i have to implement the wcf-service in order not to be dependent of the sort-order of the fields in the request?

Community
  • 1
  • 1
rudy
  • 185
  • 2
  • 11
  • 2
    You *did* request a specific order in the DataContract. The code just did what you asked it to do. If anything, you should ask "why didn't WCF discard the message?" – Panagiotis Kanavos Jul 10 '14 at 13:21
  • EDIT: i removed all order properties from the DataMember decoration, but i am still missing the value of the submitted field 'bar' if 'bar' is at the second position in the soap-request – rudy Jul 10 '14 at 16:25

2 Answers2

3

WCF wants you to send them in Order. If you don't specify an order, it defaults to some complex rules that end at alphabetical. I would think that when you remove order, it would demand Bar first. The fact that it didn't might mean something was not refreshed before it was called by SoapUI. Take a look at this other thread: https://stackoverflow.com/a/2520005/2540156

Community
  • 1
  • 1
Adam47
  • 196
  • 7
  • I'm not looking for a specific order of the fields delivered, rather, in my wcf-service, i want to receive ALL values sent by the client, which is not the case and this is what almost drives me nuts – rudy Jul 10 '14 at 16:42
  • 1
    I didn't realize I linked the same thread as @Adam47. What he's saying is the same conclusion I came to: Your customer needs to follow XML conventions and serialize `WcfNestedData` fields in alphabetical order. I find it hard to believe that any modern, built-in, XML-serializer wouldn't do this by default. Certainly it's more work for the customer to "randomize" their fields than just put them in order. – Killnine Jul 10 '14 at 19:04
  • 1
    You are not looking for them that way, but WCF is looking for them that way when it deserializes them. Most likely they do this as a performance optimization. This is one of the many little complexities in WCF that makes people want to use WebAPI with JSON. WCF still has its place, but if I'm building an internal service, I don't choose WCF unless it adds some value. – Adam47 Jul 10 '14 at 20:59
2

If you simply remove the Order property from the DataMember decorators on your WcfData object, it shouldn't require any certain order.

[DataContract]
public class WcfData
{
    [DataMember]
    public WcfDataNested NestedData { get; set; }

    public class WcfDataNested
    {
        [DataMember]
        public string Foo { get; set; }
        [DataMember]
        public string Bar { get; set; }
    }
}

EDIT: From the sound of this question, it appears that if you don't serialize alphabetically (an XML convention), the fields that are not in order may be discarded when WCF deserializes the class.

Community
  • 1
  • 1
Killnine
  • 5,728
  • 8
  • 39
  • 66
  • thanks for your answer, but this does't change anything in the behaviour of my strange scenario (see my edited answer) – rudy Jul 10 '14 at 14:27
  • why would your request not be sent with the fields in alphabetical order? I'm just trying to understand the problem you're trying to solve. – Killnine Jul 10 '14 at 16:08
  • my customers send the fields in their request in a random order. i receive the value of the property 'Bar' only, if the 'Bar'-tag appears in the request ABOVE the 'Foo'-tag. if i put the 'Bar'-tag BELOW the 'Foo'-tag , i am missing the value of 'Bar' in the function 'ReturnRequest'. i just can't see why this is happening – rudy Jul 10 '14 at 16:34
  • 1
    http://stackoverflow.com/questions/2519240/wcf-datacontract-some-fields-do-not-deserialize I think this addresses your issue. Your customers' serializer _needs_ to send the fields in alphabetical order or they may be discarded (i.e. come in as `null`) upon deserialization. – Killnine Jul 10 '14 at 19:01
  • thank you for the link. i am quite new to WCF and didn't realize that the fields MUST arrive in a specific order – rudy Jul 14 '14 at 15:22