Here's the scenario: You are writing an NetCF app and trying to call a web service from that app. You generated the code for the client proxy class using Visual Studio's "Add Web Reference" command. Code is generated, you call into it, and you run your app. The call fails with a cryptic error from the web service saying something about a malformed message. If you try the same thing from a desktop app it works perfectly. Sound familiar? Read on for the reason and solution.
I'll address the common cause of xml element mis-ordering here.
Calling web services involves serializing objects and sending the resulting xml to the web service, and deserializing the xml response back into objects. This is usually totally transparent to the developer, who just invokes a method and the magic happens behind the scenes. The serialized objects come from classes that are usually generated for you by Visual Studio or command-line tools like wsdl.exe or svcutil.exe. They are constructed based on the service WSDL in such a way that their serialized format matches what the service is expecting, and such that they can be deserialized from the xml the service will respond with. These classes are called "client proxy classes."
Both the desktop .NET Framework and the .NET Compact Framework use the XmlSerializer class for serializing and deserializing these objects. When using the WCF stack, the desktop framework will use their recently added DataContractSerializer instead of the XmlSerializer. Both of these serializers rely on reflection to query the generated client proxy classes and to generate the required xml.
The .NET runtime does not ever care about the order a given type's elements are declared. For example, the class:
class Fruit { int seeds; string color; }
Is equivalent to
class Fruit { string color; int seeds; }
This makes sense. Unfortunately though, because of this when you use reflection to query the members of a type, the order of those members is not guaranteed to be in declaration order, or even to be consistent as you switch between versions of the .NET Framework. In fact, the order in which reflection returns members did in fact change between versions 1.1 and 2.0 of the framework.
Because the serializers in .NET rely on reflection, they are affected by the non-deterministic ordering of members that reflection provides. The order of elements serialized will change with whatever order reflection provides members in.
The .NET designers anticipated this problem, and provided a way to force a specific ordering of serialized elements. The xml serializer attributes that you can decorate your serializable classes with support an Order attribute that you can use to guarantee some desired ordering of elements. For example, you could force the Fruit class used earlier to put <seeds> before <color> no matter what order reflection provides by changing the class to read like this:
class Fruit { [XmlElementAttribute(Order=1)] int seeds; [XmlElementAttribute(Order=2)] string color; }
The attributes will retain the Order property's value regardless of reflection order, and that information can be used within the serializer to keep the order to the way the app developer intended.
Although neither desktop nor NetCF's framework guarantees ordering, it so happens that desktop's serializer preserves the order better than NetCF's. Desktop's serializer isn't perfect either, but it's predictable enough that developers take its order for granted and then wonder why NetCF's serializer doesn't behave the same way.
Unfortunately, the wsdl.exe and Visual Studio IDE developers were among those developers that seem to have forgotten that ordering is not guaranteed unless explicitly defined, and so neither generate the code in the client proxy classes to set the Order properties necessary to guarantee the correct ordering. It seems they assumed that declaration order is the default, since the desktop framework (mostly) works that way.
The wsdl.exe tool does offer an "/order" switch that will set order explicitly, but unfortunately this command line tool generates code that won't compile on NetCF projects because of the limited API exposed by NetCF.
So until the code is fixed in Visual Studio and/or wsdl.exe, you have a couple of options to get your NetCF projects to call these web services that require specific order:
There are a few fixes I'm personally working on to help alleviate this inconvenience for app developers.
The XmlSerializer cannot guarantee element order either on desktop .NET Framework or the .NET Compact Framework unless the developer gives the order explicitly, although in some cases the "default" ordering will behave as you expect and in some cases it won't.
The bottom line: where element order is important, use XmlElementAttribute.Order, XmlArrayAttribute.Order, and the other ordering attributes as necessary.