What is required is that it has a way to resolve members to numeric keys. This can take the form of inline attributes - for example, it allows [DataContract]/[DataMember(Order=key)], [XmlType]/[XmlElement(Order=key)], or [ProtoContract]/[ProtoMember(key)].
There are also options via [DataContract] to infer the contract alphabetically, but this is only safe if your contract type is not going to change in the future; to do this, add:
[ProtoContract(InferTagFromName = true)]
to the type (perhaps in a partial, see below). This applies directly to the scenario you present, where [DataMember] indicates the members, but there is no defined Order. Personally I prefer explicit layouts, for stability.
Another option doesn't even need hints like [DataMember]; you can ask it to apply either BinaryFormatter rules (all fields, public or private), or XmlSerializer rules (public members, properties or fields); again, though, this is very unstable if your type changes!
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
But; another common scenario is that you have types coming from a generator, that you can't conveniently edit, since any edits would get lost at re-generation; for that scenario, partial classes can be helpful. You can't add attributes to members via attributes, but [ProtoPartialMember] can help here. For example, in a separate code file:
[ProtoContract]
[ProtoPartialMember(key, memberName)]
[ProtoPartialMember(anotherKey, anotherMemberName)]
...
public partial class Order {}
Sometimes, you have no access whatsoever to the type, so adding attributes of any kind is not an option. If your scenario is as you describe ([DataContract/[DataMember], noOrder`), then a lazy option is to enable this globally:
Serializer.GlobalOptions.InferTagFromName = true;
or in v2:
RuntimeTypeModel.Default.InferTagFromNameDefault = true;
For more complex scenarios, v2 has a new MetaType model devoted to this, where you can configure the layout at runtime:
RuntimeTypeModel.Default.Add(typeof(Order), false)
.Add(key, memberName).Add(anotherKey, anotherMemberName);
or if your keys are 1, 2, 3, ... then just:
RuntimeTypeModel.Default.Add(typeof(Order), false)
.Add(memberName, anotherMemberName, ...);
(there are a myriad of options on the MetaType to control all aspects of the serialization)
I think that covers most of the options here!